首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用getaddrinfo连接到使用外部IP的服务器?

如何使用getaddrinfo连接到使用外部IP的服务器?
EN

Stack Overflow用户
提问于 2013-05-04 09:23:44
回答 1查看 21.3K关注 0票数 8

我正在编写一个小型的C客户机/服务器应用程序,但当使用外部IP地址时,我无法使连接工作。客户机和服务器的代码都取自这里,特别是客户端:

代码语言:javascript
复制
    char *default_server_name = "localhost";
    char *server_name = NULL;
    int nport = DEFAULT_DAMA_PORT;
    char port[15];

    // Parse the command line options
    if (parse_options(argc, argv, &server_name, &nport) < 0) {
        return -1;
    }

    if (server_name == NULL) {
        server_name = default_server_name;
    }

    snprintf(port, 15, "%d", nport);

    // Connect to the server
    int client_socket;
    struct addrinfo hints, *servinfo, *p;
    int rv;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    if ((rv = getaddrinfo(server_name, port, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        exit(1);
    }

    for (p=servinfo; p != NULL; p = p->ai_next) {
        if ((client_socket = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
#ifdef DEBUG
            perror("socket");
#endif
            continue;
        }

        if (connect(client_socket, p->ai_addr, p->ai_addrlen) == -1) {
            close(client_socket);
#ifdef DEBUG
            perror("connect");
#endif
            continue;
        }

        // Connected succesfully!
        break;
    }

    if (p == NULL) {
        // The loop wasn't able to connect to the server
        fprintf(stderr, "Couldn't connect to the server\n.");
        exit(1);
    }

而服务器:

代码语言:javascript
复制
    int nport;
    char port[15];
    if (parse_options(argc, argv, &nport) < 0) {
        return -1;
    }

    snprintf(port, 15, "%d", nport);

    int server_socket;
    struct addrinfo hints, *servinfo, *p;
    int rv;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        exit(1);
    }

    for (p=servinfo; p != NULL; p = p->ai_next) {
        if ((server_socket = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
#ifdef DEBUG
            perror("socket");
#endif
            continue;
        }

        if (bind(server_socket, p->ai_addr, p->ai_addrlen) == -1) {
            close(server_socket);
#ifdef DEBUG
            perror("bind");
#endif
            continue;
        }

        // We binded successfully!
        break;
    }

    if (p == NULL) {
        fprintf(stderr, "failed to bind socket\n");
        exit(2);
    }

    int pl_one, pl_two;
    socklen_t pl_one_len, pl_two_len;
    struct sockaddr_in pl_one_addr, pl_two_addr;

    if (listen(server_socket, 2) < 0) {
        fatal_error("Error in syscall listen.", 2);
    }

    // Get the two clients connections.
    pl_one_len = sizeof(pl_one_addr);
    pl_one = accept(server_socket,
                    (struct sockaddr *)&pl_one_addr,
                    &pl_one_len);
    if (pl_one < 0) {
        fatal_error("Error in syscall accept.", 3);
    }

    pl_two_len = sizeof(pl_two_addr);
    pl_two = accept(server_socket,
                    (struct sockaddr *)&pl_two_addr,
                    &pl_two_len);
    if (pl_two < 0) {
        fatal_error("Error in syscall accept.", 3);
    }

如果我在命令行中指定了我的机器的IP,因此客户机中的server_name被设置为像151.51.xxx.xxx这样的字符串,那么套接字就无法连接到服务器。同时,使用127.0.0.1也显示了相同的行为,这使我认为当文档声明:

您感兴趣的主机名位于nodename参数中。地址可以是主机名,如"www.example.com",也可以是IPv4或IPv6地址(作为字符串传递)。

只是开玩笑而已。

我是不是做错了什么?防火墙是否存在一些问题,使客户端无法使用IP地址进行连接?

注意:我已经搜索了很多这个问题,有些人说要避免使用getaddrinfo并直接填充INADDR_ANY,但是getaddrinfo文档指出,将NULL作为nodename传递应该已经用INADDR_ANY填充地址,所以当新方法自动完成时,我不明白为什么要使用旧的方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-04 11:20:16

正如注释中所写的,您正在尝试连接到位于路由器后面的网络中的服务器。

127.0.0.1localhost是操作系统的重定向,不会经过路由器。这就是为什么它对你有用。

如果指定外部ip地址,则连接是通过路由器进行的,您使用的端口需要在路由器配置中转发。默认情况下,任何普通家庭互联网终端用户路由器都会阻止来自任何端口的传入连接。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16372700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档