UDP 套接字 select() 在某些情况下无延迟(超时)返回 1



我在开发客户端应用程序时遇到了问题。

我想在我的应用程序中使用非阻塞 UDP 套接字与服务器通信。我正在使用Windows上的winsock2库。

但。。。出于某种原因,我在某些情况下select()功能有奇怪的行为:

套接字
  1. 没有绑定地址和端口(它是客户端套接字,所以不需要它(。
  2. select()之前,我通过调用将数据发送到我的本地地址和某个端口sendto
    • 例如:192.168.1.2

在这些条件下,select()立即(甚至无需等待超时(返回1。就像我有一些数据包准备好接收一样。 但如果打电话recvFrom那么它肯定会返回-1


  1. 如果我将数据包从客户端发送到任何其他地址(不是我在 LAN 上的地址(,则select()按预期工作。
  2. 此外,如果在调用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;
}

如果您从未绑定的 UDP 套接字发送数据包,操作系统将为您选择一个可用的端口并将套接字绑定到该端口 - UDP 协议要求发送端口具有要发送的地址。

因此,如果您发送的数据包产生响应,那么选择返回 1 是完全有意义的 - 这是对您发送的数据包的响应。

最新更新