繁体   English   中英

recvfrom()错误10035使用非阻塞套接字

[英]recvfrom() error 10035 using non-blocking sockets

我正在使用ioctlsocket()函数使我的套接字无阻塞但是当我调用recvfrom()时,我得到错误10035( WSAEWOULDBLOCK )。

u_long mode = 1;
ioctlsocket(newSocketIdentifier, FIONBIO, &mode);

while(1)
   {
      if((recv_len = recvfrom(newSocketIdentifier, receiveBuffer, sizeof(receiveBuffer), 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
      {
         char err[128];
         itoa(WSAGetLastError(),err,10);
         MessageBox( NULL,"Could not Receive Data",err,MB_ICONINFORMATION);
         BREAK;
      }
   }

任何人都可以解释为什么会这样吗? :(

如果没有可用数据,这是正常的。 代码是WSAEWOULDBLOCK(参见此表)并且意味着,在阻塞端口上,该函数必须等待直到它可以被服务。

   while(1)
   {
      if((recv_len = recvfrom(newSocketIdentifier, receiveBuffer, sizeof(receiveBuffer), 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
      { 
         int ierr= WSAGetLastError();
         if (ierr==WSAEWOULDBLOCK) {  // currently no data available
             Sleep(50);  // wait and try again
             continue; 
         }

         // Other errors
         char err[128];
         itoa(ierr,err,10);
         MessageBox( NULL,"Could not Receive Data",err,MB_ICONINFORMATION);
         break;
      }
   }

我不能同意这是“正常”,如上所述。

在您的recvfrom调用中,您将收到recv_len的错误。 我建议检查该值 - 它将是SOCKET_ERROR并通过调用WSAGetLastErrorenter您将看到错误WSAEWOULDBLOCK

我不是(Windows)套接字专家,但根据我的测试,我不能使用ioctlsocketrecvfrom组合在非阻塞模式下通过UDP接收数据(我在你的例子中做了同样的事情)。

我打算使用selectrecvfrom组合,最小可能超时(1us)。 我现在还不知道任何其他可能更好的解决方案。

注意:您还应检查ioctlsocket的返回值ioctlsocket存在可能的错误。

我今天晚些时候会提供我的代码示例。

更新(按照承诺添加代码):

/* define list of sockets for function select(..) */
fd_set readfds;
/* define timeout for function select(..) */
TIMEVAL tv;
/* timeout: 1us */
tv.tv_usec = 1;
/* timeout: 0s */
tv.tv_sec = 0;
/* just 1 socket is used */
readfds.fd_count = 1;
readfds.fd_array[0] = receivingSocket;
/* determine the status of one or more sockets with timeout */
int selectReturnValue = select(0, &readfds, 0, 0, &tv);
/* check return value of the call of function select(..) */
switch (selectReturnValue)
{
  /* select(..) function timeout */
  case 0:
    /* time limit expired */
    break;
  /* select(..) function error */
  case SOCKET_ERROR:
    /* check the error status for the last windows sockets operation */
    selectError(WSAGetLastError());
    break;
  /* no timeout and no error */
  default:
    /* receive data from UDP */
    resultOfrecvfrom = recvfrom(receivingSocket, receivingBuffer, sizeof(receivingBuffer), 0, (SOCKADDR *)&serverReceptionInfo, &serverReceptionInfoLength);
    /* check result of call of recvfrom(..) */
    switch (resultOfrecvfrom)
    {
      /* connection has been gracefully closed  */
      case 0:
        /* socket was closed */
        break;
      /* socket error occurred during last call of socket operation */
      case SOCKET_ERROR:
        /* check the error status for the last Windows Sockets operation */
        recvfromError(WSAGetLastError());
        break;
      /* resultOfrecvfrom amount of data received */
      default:            
        /* ... add your code here */
        break;
    }
    break;      
}

如果需要更多,我只是复制了我的代码的关键部分,请在评论中告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM