Я столкнулся с проблемой при разработке клиентского приложения.
Я хочу использовать неблокирующие сокеты UDP в моем приложении для связи с сервером. Я использую библиотеку winsock2
в Windows.
Но ... Почему-то у меня странное поведение функции select()
при некоторых условиях:
- Сокет не имеет привязанного адреса и порта (это сокет на стороне клиента, поэтому он не нужен).
- До
select()
Я отправляю данные на мой локальный адрес и на какой-то порт с вызовом sendto
.
При этих условиях 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;
}