gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 17:13:37 25 4
gpt4 key购买 nike

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

    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);
}

当服务器:

    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 显示相同的行为,这让我觉得当文档说明时:

The host name that you're interested in goes in the nodename parameter. The address can be either a host name, like "www.example.com", or an IPv4 or IPv6 address (passed as a string).

这只是个玩笑。

我做错了什么吗?防火墙等是否有问题阻止客户端使用 IP 地址进行连接?

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

最佳答案

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

127.0.0.1localhost 是操作系统的重定向,不会通过路由器。这就是它对您有用的原因。

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

关于c - 如何使用 getaddrinfo 连接到使用外部 IP 的服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16372700/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com