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!
if((nError == SOCKET_ERROR) || (nError == 0))
WSAGetLastError();
else
; // handle success
That's how it should look, and not how you did it.
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);