I am having an issue in my recv() loop for winsock. I am trying to terminate the loop when iResult==0, however, the loop only ends when the socket closes. It appears to be hanging at the very last recv() where iResult would equal 0. So any ideas on how to terminate the loop effectively? My ultimate goal (whether iResult == 0 or not; perhaps I am going about this the wrong way) is to stop the loop when all the sent information has been read. Here is the loop.
do
{
iResult = recv(socket, recvbuf, BUFLEN-1, 0);
if(iResult > 0){
// Null byte :)
// Remove that garbage >:(
recvbuf[iResult] = '\0';
printf("Recvbuf: %s\n\n\niResult: %d\n",recvbuf,iResult);
continue; // working properly
}
else if(iResult == 0)
// Connection closed properly
break;
else
{
printf("ERROR! %ld",WSAGetLastError());
break;
}
} while(iResult > 0);
Like I said, I am receiving all the data, I just cannot exit the loop. The next step would to be write data back to the server, but it hangs here until ping timeout. Socket is SOCK_STREAM and BUFLEN is defined as 0x200
Thanks
By default, instead of returning 0, recv
blocks if there's no data to receive :
If no incoming data is available at the socket, the recv call blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect functions can be used to determine when more data arrives.
You can use ioctlsocket to put the socket in non-blocking mode:
u_long iMode = 1;
ioctlsocket(socket, FIONBIO, &iMode);
EDIT: Here's the setsockopt suggestion that I made in an earlier rev, then removed (see comments):
You can use the setsockopt function with the
SO_RCVTIMEO
option to set the socket to timeout onrecv
if no data is available.
When you design a TCP communication mechanism you have to define message boundaries. (often \r\n). In of itself, tcp doesn't know about boundaries; you have to do this yourself. The recv() call may not always return on a message boundary. One send() might get split into multiple recv()-s on the other end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With