未连接的UDP套接字上的WSARecvFrom不返回

时间:2011-03-28 17:48:59

标签: c++ udp winsock

我正在编写一个测试UDP网络服务的小程序。允许服务的实现为会话创建一个新的套接字并从那里响应客户端,然后客户端需要与该地址通信(类似于TFTP)。

最小客户端无错误检查如下所示:

int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

sockaddr_in destaddr = { ... };
MSGBUF msg[] = { ... };
DWORD sent;
WSASendTo(fd, msg, sizeof msg / sizeof *msg, &sent, 0, (sockaddr *)sa, sizeof sa, 0, 0);

char buffer[4096];
MSGBUF rcvmsg = { sizeof buffer, buffer };
DWORD received;
sockaddr_storage sa;
socklen_t sa_len = sizeof sa;
DWORD flags = 0;
WSARecvFrom(fd, &rcvmsg, 1, &received, &flags, (sockaddr *)&sa, &sa_len, 0, 0);

如果服务器从发送初始消息的相同地址和端口响应,则客户端正常工作,但是从另一个端口的回复被静默丢弃,客户端挂起WSARecvFrom

将套接字明确绑定到{ AF_INET, INADDR_ANY, 0 }以强制分配本地端口,或调用listen(fd, 5);没有任何区别,正如预期的那样。

WSASendTo中是否存在隐式连接UDP套接字的内容,如果有,我该怎么做才能避免这种情况?

2 个答案:

答案 0 :(得分:2)

UDP没有连接。数据报被发送到端口和从端口发送;这是单向沟通。

在我看来,您的服务器正在为自己分配一个临时端口(即在sockaddr_in中传递0作为端口),而不是使用特定端口。这不行。

由于UDP没有连接概念,因此每次发送数据时,都可以从不同的端口发送;第一个发送不保留它给出的端口,它只是从它发送一个数据报,然后让它去。

您的服务器应该绑定到特定端口。

答案 1 :(得分:0)

嗯,这是一个防火墙问题。将应用程序添加到允许接收传入流量的程序列表中可以解决问题。