我正在尝试编写一个通过UDP接收查询并通过UDP发送响应的服务器.我遇到的问题是,当我尝试发送响应时,我收到"101网络无法访问"错误.
根据这里的问题,我尝试通过取出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);
Run Code Online (Sandbox Code Playgroud)
是的,我有错误检查所有这些电话(这就是我发现问题的方式); 为了简洁起见,它被简单地遗漏在这里.
您不应该使用a struct sockaddr来存储recvfrom调用中的源地址,它可能无法表示IP套接字地址.
你应该使用一个struct sockaddr_inIPv4地址或一个struct sockaddr_in6IPv6地址,或者更好的是,a 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);
Run Code Online (Sandbox Code Playgroud)