简体   繁体   English

套接字UDP:使用Sendto()中Recvfrom()的发件人信息失败

[英]Sockets UDP: Using Sender Info from Recvfrom() in Sendto() Fails

I'm trying to write a server that that receives a query via UDP and sends a response via UDP. 我正在尝试编写一个通过UDP接收查询并通过UDP发送响应的服务器。 The problem I'm running into is that when I try to send my response, I get a "101 Network is unreachable" error. 我遇到的问题是,当我尝试发送我的响应时,我收到“101网络无法访问”错误。

Based on the question here I tried to resolve this by taking out the hints.ai_flags = AI_PASSIVE; 根据这里的问题我试图通过取出hints.ai_flags = AI_PASSIVE;来解决这个问题hints.ai_flags = AI_PASSIVE; line, but then the server never successfully gets the message. 但是服务器从未成功获取消息。 I looked at the man page for addrinfo and it sounds like if the AI_PASSIVE flag is set, the socket can only recvfrom() , while if it's not set, the socket can only sendto() . 我查看了addrinfo的手册页,听起来如果设置了AI_PASSIVE标志,套接字只能recvfrom() ,而如果没有设置,套接字只能发送到sendto() I've seen a bunch of examples online with people doing both from a single socket, though; 我在网上看过很多例子,人们从一个插槽中做两件事; what am I missing? 我错过了什么?

Relevant code: 相关代码:

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

Yes, I have error checking for all those calls (that's how I found the problem); 是的,我有错误检查所有这些电话(这就是我发现问题的方式); it's simply been left out here for brevity's sake. 为了简洁起见,它被简单地遗漏在这里。

You shouldn't use a struct sockaddr to store the source address in the recvfrom call, it might not be able to represent an IP socket address. 您不应该使用struct sockaddrrecvfrom调用中存储源地址,它可能无法表示IP套接字地址。

You're supposed to use a struct sockaddr_in for an IPv4 address or a struct sockaddr_in6 for an IPv6 address, or better yet, a struct sockaddr_storage to cope with either. 你应该使用struct sockaddr_in作为IPv4地址,或者使用struct sockaddr_in6作为IPv6地址,或者更好的是,使用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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM