【发布时间】:2018-12-09 12:24:22
【问题描述】:
我在开发客户端应用程序时遇到了问题。
我想在我的应用程序中使用非阻塞 UDP 套接字与服务器通信。我在 Windows 上使用 winsock2 库。
但是...由于某种原因,在某些情况下,select() 函数的行为很奇怪:
- 套接字没有绑定地址和端口(它是客户端套接字,所以不需要它)。
- 在
select()之前,我通过sendto调用将数据发送到我的本地 地址和某个端口。- 例如:
192.168.1.2
- 例如:
在这些条件下select() 立即(甚至无需等待超时)返回1。就像我准备好接收一些数据包一样。
但是如果调用recvFrom,那么它肯定会返回-1。
- 如果我将数据包从客户端发送到任何其他地址(这不是我在 LAN 上的地址),那么
select()将按预期工作。 - 如果在调用
select()之前不向任何地址发送任何数据包,select()也可以正常工作。
套接字初始化方法:
bool CUdpSocket::initialize()
{
_handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
... error processing code, returns false if error...
}
使用select() 的方法。此方法适用于服务器套接字(具有绑定地址和端口)。
bool CUdpSocket::waitData(s32 timeout_ms)
{
fd_set readset;
int result;
struct timeval tv;
// Initialize the set.
FD_ZERO(&readset);
FD_SET(_handle, &readset);
// Initialize time out struct.
tv.tv_sec = 0;
tv.tv_usec = timeout_ms * 1000;
result = select(_handle + 1, &readset, NULL, NULL, &tv);
// Timeout with no data.
if (result == 0) {
return false; // Get out of here!
}
// Error.
if (result < 0) {
// TODO: Maybe throw exception or do something.
return false;
} else if (!FD_ISSET(_handle, &readset)) {
return false; // No data!
}
// There is some data!
return true;
}
【问题讨论】:
-
recvfrom()会返回 -1 什么错误? -
@EJP 嗯...忘记检查了。
recvFrom调用后的 WSAGetLastError 返回代码 10054 (WSAECONNRESET)。 -
Google 是你的朋友:Google "WSAECONNRESET UDP" - 热门搜索:stackoverflow.com/questions/30749423/…,根据下面@ChrisDodd 的评论。我希望你能从中学到一些关于挖掘自己的问题的知识。