Winsock recv()不会阻止

时间:2010-11-11 20:51:04

标签: c++ winsock

我刚刚编译了这段代码: http://www.win32developer.com/tutorial/winsock/winsock_tutorial_2.shtm

我添加了一些代码,因此它在无限循环中执行recv()。我的问题是,如果没有数据要读,它仍然不会阻止。

如果我认为recv应该阻止我的情况,我完全错了吗?

我添加的代码是:

for(;;)
{
  char buffer[1000];
  memset(buffer,0,999);
  int inDataLength = recv(Socket,buffer,1000,0);

  int nError=WSAGetLastError();
  if(nError!=WSAEWOULDBLOCK&&nError!=0)
  {
    std::cout<<"Winsock error code: "<<nError<<"\r\n";
    std::cout<<"Client disconnected!\r\n";

    // Shutdown our socket
    shutdown(Socket,SD_SEND);

    // Close our socket entirely
    closesocket(Socket);

    break;
  }
}

最后是std::cout<<"Client connected!\r\n\r\n";行之后。 我知道我从一个“非阻塞”的例子中复制了这个,但是我不认为这个代码应该做任何非阻塞的事情,但是,我的for循环运行得像疯了一样!

3 个答案:

答案 0 :(得分:5)

默认情况下,

recv应该阻止,除非出现套接字错误或者您明确将套接字设置为非阻塞。务必检查错误的返回值。有关详细信息,请参阅recv上的微软MSDN文章。

答案 1 :(得分:2)

循环没有正确检查错误。它需要更像这样:

char buffer[1000]; 
int inDataLength;

do 
    {
    inDataLength = recv(Socket, buffer, sizeof(buffer), 0); 
    if (inDataLength > 0)
        {
        // inDataLength number of bytes were received, use buffer as needed...
        continue;
        }

    if (inDataLength == 0)
        {
        std::cout << "Client disconnected!" << std::endl; 
        break;
        }

    int nError = WSAGetLastError(); 
    if (nError != WSAEWOULDBLOCK)
        {
        std::cout << "Winsock error code: " << nError << std::endl; 
        break;
        }

    // optionally call select() here to wait for the socket
    // to receive data before calling recv() again...
    /*
    fd_set fd;
    FD_ZERO(&fd);
    FD_SET(Socket, &fd);

    timeval tv;
    tv.tv_sec = ...;
    tv.tv_usec = ...;

    nError = select(Socket+1, &fd, NULL, NULL, &tv);
    if (nError == 0)
        {
        std::cout << "Timeout waiting for data" << std::endl; 
        break;
        }

    if (nError == SOCKET_ERROR)
        {
        nError = WSAGetLastError();
        std::cout << "Winsock error code: " << nError << std::endl; 
        break;
        }
    */
    } 
while (true);

// Shutdown our socket 
shutdown(Socket, SD_SEND); 

// Close our socket entirely 
closesocket(Socket); 

答案 2 :(得分:1)

if((nError == SOCKET_ERROR) || (nError == 0))
    WSAGetLastError();
else
    ; // handle success

它应该是什么样子,而不是你是怎么做的。