在开发客户端应用程序时遇到问题。
我想在应用程序中使用非阻塞UDP套接字与服务器通信。我在Windows上使用winsock2
库。
但是...由于某些原因,在某些情况下,我对select()
函数的行为感到奇怪:
select()
之前,我会通过sendto
呼叫将数据发送到我的本地地址和某些端口。
192.168.1.2
在这些情况下,select()
立即(甚至没有等待超时)返回1
。就像我有一些小包准备接收。
但是,如果调用recvFrom
,那么它将肯定返回-1
。
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;
}
答案 0 :(得分:0)
如果您从未绑定的UDP套接字发送数据包,则操作系统将为您选择一个使用的端口,并将该套接字绑定到该端口-UDP协议要求,该发送端口必须有一个地址发送。
因此,如果您要发送的数据包产生了响应,那么选择返回1就是很有意义的-这就是对您发送的数据包的响应。