Winsock2 select()返回WSAEINVAL(错误10022)

时间:2017-08-09 21:49:29

标签: c++ select winsock2

我有给定的代码:

#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的示例。有可能吗?我需要在客户端代码中执行此操作,以使程序在未连接到服务器的情况下短时间内休眠。

2 个答案:

答案 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(),你就会变得金色。