2010-11-11 50 views
0

我刚才编译此代码: http://www.win32developer.com/tutorial/winsock/winsock_tutorial_2.shtm的Winsock的recv()不阻止

我增加了一些代码,这样它的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循环像疯了一样运行!

+1

你能粘贴你写的附加代码吗? – chrisaycock 2010-11-11 20:56:54

+0

您是否使用任何WSAsync ...调用? – Rob 2010-11-11 21:15:52

+0

你有什么样的客户端连接到你的服务器? – chrisaycock 2010-11-11 21:22:17

回答

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

这就是它应该如何看,而不是你是如何做到的。

+0

只是为了澄清:'WSAEWOULDBLOCK'非常适合**非阻塞的套接字。而且,如果返回码是'SOCKET_ERROR'(-1),你应该检查WSAGetLastError()。 – Poni 2010-11-11 23:19:01

+0

@Rob:nError如何获得它的值,然后如果我不使用WSAGetLastError()? – 2010-11-12 09:05:49

+0

@Poni:抱歉,我的意思是波尼,而不是罗伯。 – 2010-11-12 11:30:27

5

recv应该是默认阻止,除非有一个套接字错误或明确设置套接字非阻塞。一定要检查错误的返回值。欲了解更多信息,请参阅recv上的Microsofts MSDN文章。

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