我有给定的代码:
#include <winsock2.h>
#include <sys/time.h>
#include <iostream>
int main()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
std::cout << "WSA Initialization failed!" << std::endl;
WSACleanup();
}
timeval time;
time.tv_sec = 1;
time.tv_usec = 0;
int retval = select(0, NULL, NULL, NULL, &time);
if (retval == SOCKET_ERROR)
{
std::cout << WSAGetLastError() << std::endl;
}
return 0;
}
它打印10022
,这意味着错误WSAEINVAL。根据{{3}},我只能在以下情况下收到此错误:
WSAEINVAL:超时值无效,或者所有三个描述符参数均为空。
但是,我看到一些调用select()而没有任何FD_SET
的示例。有可能吗?我需要在客户端代码中执行此操作,以使程序在未连接到服务器的情况下短时间内休眠。
答案 0 :(得分:0)
来自臭名昭着的冒犯性Winsock 'lame list':
使用三个空的FD_SET和一个有效的TIMEOUT结构作为一个套筒延迟函数调用select()。
不可原谅的跛脚。
请注意拼写错误。这份文件值得一读,如果你能忍受的话,只是为了看到傲慢无比的深度。如果他们已经重新出现,或者发现他们没有发明套接字API,你可以尝试使用空FD集而不是空参数,但我并不抱太大希望。
答案 1 :(得分:0)
但是,我已经看到一些调用select()而不使用any的示例 的fd_sets。
它适用于大多数操作系统(不是Windows)。
是否有可能[在Windows下]?
不是直接的,但它很容易在select()周围滚动自己的包装器,即使在Windows下也能提供你想要的行为:
int proper_select(int largestFileDescriptorValuePlusOne, struct fd_set * readFS, struct fd_set * writeFS, struct fd_set * exceptFS, struct timeVal * timeout)
{
#ifdef _WIN32
// Note that you *do* need to pass in the correct value
// for (largestFileDescriptorValuePlusOne) for this wrapper
// to work; Windows programmers sometimes just pass in a dummy value,
// because the current Windows implementation of select() ignores the
// parameter, but that's a portability-killing hack and wrong,
// so don't do it!
if ((largestFileDescriptorValuePlusOne <= 0)&&(timeout != NULL))
{
// Windows select() will error out on a timeout-only call, so call Sleep() instead.
Sleep(((timeout->tv_sec*1000000)+timeout->tv_usec)/1000);
return 0;
}
#endif
// in all other cases we just pass through to the normal select() call
return select(maxFD, readFS, writeFS, exceptFS, timeout);
}
...然后只需调用proper_select()而不是select(),你就会变得金色。