简体   繁体   中英

Winsock recv() does not block

I have just compiled this code: http://www.win32developer.com/tutorial/winsock/winsock_tutorial_2.shtm

I have added some codes so it does recv(), in an infinite loop. My problem, if there is no data to read, it still does not block.

Am I totally mistaken if I think recv should block in my case?

The code I have added is:

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;
  }
}

It is at the end, after the std::cout<<"Client connected!\\r\\n\\r\\n"; line. I know I copied this from a "non blocking" example, but I dont think this code should do anything nonblocking really, still, my for loop is running like mad!

recv should block by default, unless there's a socket error or you explicitly set the socket to non-blocking. Be sure to check the return value for error. For more information see the Microsofts MSDN article on recv .

The loop is not checking for errors correctly. It needs to be more like this instead:

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); 
if((nError == SOCKET_ERROR) || (nError == 0))
    WSAGetLastError();
else
    ; // handle success

That's how it should look, and not how you did it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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