我刚刚编译了这段代码: 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循环运行得像疯了一样!
答案 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
它应该是什么样子,而不是你是怎么做的。