0

我正在使用 WSAWaitforMultipleEvents() 函数,并且我认为这使我的套接字非阻塞,即 recvfrom() 仅在生成 FD_READ 事件并且套接字上可以读取数据时才调用。所以,我的 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
          }
        }
     }
  }
4

2 回答 2

2

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

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

于 2013-06-12T05:37:29.323 回答
0

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

无论lNetworkEvents值如何,WSAEventSelect函数都会自动将 socket 设置为非阻塞模式。

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

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

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

于 2015-04-01T14:12:34.133 回答