Winsock recv () не блокирует - PullRequest
0 голосов
/ 11 ноября 2010

Я только что скомпилировал этот код: 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 ]

5 голосов
/ 12 ноября 2010

recv должен блокироваться по умолчанию, если нет ошибки сокета или вы явно не установили сокет как неблокирующий.Обязательно проверьте возвращаемое значение на наличие ошибки.Для получения дополнительной информации см. Статью Microsoft MSDN на recv .

2 голосов
/ 30 июня 2012

Цикл не проверяет на ошибки правильно. Это должно быть больше так:

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); 
1 голос
/ 12 ноября 2010
if((nError == SOCKET_ERROR) || (nError == 0))
    WSAGetLastError();
else
    ; // handle success

Вот так это должно выглядеть, а не то, как ты это сделал.

...