5

我正在尝试编写一个通过 UDP 接收查询并通过 UDP 发送响应的服务器。我遇到的问题是,当我尝试发送响应时,出现“101 Network is unreachable”错误。

根据这里的问题,我试图通过拔掉hints.ai_flags = AI_PASSIVE;线路来解决这个问题,但是服务器永远不会成功地收到消息。我查看了手册页,addrinfo听起来如果AI_PASSIVE设置了标志,则套接字只能recvfrom(),而如果未设置,则套接字只能sendto()。不过,我在网上看到了很多例子,人们从一个套接字同时做这两种操作;我错过了什么?

相关代码:

struct addrinfo hints;
struct addrinfo *serverinfo;
memset(&hints,0,sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;

int status = getaddrinfo(NULL, port, &hints, &serverinfo);
int sock = socket(serverinfo->ai_family, serverinfo->ai_socktype, serverinfo->ai_protocol);
status = bind(sock, serverinfo->ai_addr, serverinfo->ai_addrlen);
freeaddrinfo(serverinfo);

// poll until there's an incoming packet

struct sockaddr sender;
socklen_t sendsize = sizeof(sender);
bzero(&sender, sizeof(sender));

recvfrom(sock, message, sizeof(message), 0, &sender, &sendsize);

// message processing

sendto(sock, response, sizeof(response), 0, (struct sockaddr *)&sender, sendsize);

是的,我对所有这些调用进行了错误检查(这就是我发现问题的方式);为了简洁起见,它被简单地忽略了。

4

1 回答 1

9

您不应该使用 astruct sockaddrrecvfrom调用中存储源地址,它可能无法表示 IP 套接字地址。

您应该将 astruct sockaddr_in用于 IPv4 地址或 astruct sockaddr_in6用于 IPv6 地址,或者更好的是,使用 astruct sockaddr_storage来处理其中任何一个。

struct sockaddr_storage sender;
socklen_t sendsize = sizeof(sender);
bzero(&sender, sizeof(sender));

recvfrom(sock, message, sizeof(message), 0, (struct sockaddr*)&sender, &sendsize);
于 2012-04-19T22:31:34.500 回答