我正在编写一个测试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套接字的内容,如果有,我该怎么做才能避免这种情况?
答案 0 :(得分:2)
UDP没有连接。数据报被发送到端口和从端口发送;这是单向沟通。
在我看来,您的服务器正在为自己分配一个临时端口(即在sockaddr_in
中传递0作为端口),而不是使用特定端口。这不行。
由于UDP没有连接概念,因此每次发送数据时,都可以从不同的端口发送;第一个发送不保留它给出的端口,它只是从它发送一个数据报,然后让它去。
您的服务器应该绑定到特定端口。
答案 1 :(得分:0)