c - 套接字 UDP : Using Sender Info from Recvfrom() in Sendto() Fails

标签 c sockets udp

我正在尝试编写一个通过 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/

相关文章:

c - 用 g_unix_signal_add 添加后不调用中断句柄

c - 父进程和子进程共享一个IPC共享内存

c - 在 C 中使用指向未命名结构的指针?

Java套接字服务器->只接受一个请求然后停止接受?

c++ - 如何制作多客户端 UDP 服务器

我可以实现从基于 WCF 的 HTTP 服务到 gSOAP c/Linux 客户端的回调吗?

sockets - 使用 J2ME 进行套接字编程

tcp - 如果 wireshark 无法识别某些类型的协议(protocol)(RTSP、RTP、RTCP),我如何强制其破译这些协议(protocol)?

Android 在发送 UDP 数据包时抛出异常

python - TCP 线程 python