使用WSAWaitforMultipleEvents()的非阻塞套接字函数的概念

时间:2013-06-12 05:28:27

标签: c windows sockets networking udp

我正在使用WSAWaitforMultipleEvents()函数,我认为这使得我的套接字无阻塞,即仅当生成FD_READ事件并且数据在套接字处可读时才调用recvfrom()。所以,我的recvfrom()不会阻止调用。

我的方法是使套接字无阻塞正确吗?因为现在我觉得我的程序仍在阻止等待事件,所以它看起来并不是非阻塞的。我正在添加一段代码以求帮助。

提前致谢:)

   while(1)
   {
     waitRet = WSAWaitForMultipleEvents(1, &hEvent, FALSE, INFINITE, FALSE);
     if(WSAEnumNetworkEvents(newSocketIdentifier,hEvent,&events) == SOCKET_ERROR)
     {
      "FAILURE"
      continue;
     }
     else
     {   //else event occurred
        if(events.lNetworkEvents & FD_READ)
        {
           //FD_READ
          if((recv_len = recvfrom(newSocketIdentifier, receiveBuffer, sizeof(receiveBuffer), 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
          {
             //error in recvfrom
          }
          else
          {
            //recvfrom() succeeded
          }
        }
     }
  }

2 个答案:

答案 0 :(得分:2)

您可以通过使用(recvfrom()不会阻塞句柄来使其句柄无阻塞)以更简单的方式使套接字无阻塞:

ioctlsocket(<socket handle>, FIONBIO, <make it non-zero to enable non-blocking>)

答案 1 :(得分:0)

由于您使用的是WSAWaitForMultipleEvents,因此您已经创建了一个事件(使用WSACreateEvent)并将其连接到套接字(使用WSAEventSelect)。从MSDN文档:

  

WSAEventSelect 函数自动将套接字 s 设置为非阻塞   模式,无论 lNetworkEvents 的值。

因此,以下代码隐式将套接字设置为非阻塞模式:

WSAEVENT hEvent = WSACreateEvent();
WSAEventSelect( newSocketIdentifier, hSocketEvent, FD_READ );

WSAWaitForMultipleEvents将“阻塞”直到它收到一个事件(或超时),但这与套接字的阻塞/非阻塞模式无关。