我正在尝试编写一个通过 UDP 接收查询并通过 UDP 发送响应的服务器。我遇到的问题是,当我尝试发送响应时,出现“101 网络无法访问”错误。
基于问题here我试图通过删除 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);
是的,我对所有这些调用进行了错误检查(这就是我发现问题的方式);为简洁起见,它只是被排除在外。
最佳答案
您不应该使用 struct sockaddr
来存储 recvfrom
调用中的源地址,它可能无法表示 IP 套接字地址。
你应该为 IPv4 地址使用 struct sockaddr_in
或为 IPv6 地址使用 struct sockaddr_in6
,或者更好的是,struct 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);
关于c - 套接字 UDP : Using Sender Info from Recvfrom() in Sendto() Fails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10237163/