views:

454

answers:

5

Hi,

I am facing an issue with recv() and send() winsock api. Recv() hangs while receving the last packet.

Problem Description:-

System A's app is writing data over a non-blocking socket and system B's app is receiving data over a blocking socket in chunks of 64k.

It seems that while reading probably the last packet of 64k, which may less than or equal to 64k, the receive freezes. I am not sure if the receive of the last packet or send of the last packet is an issue, but I am observing this issue intermittently in our legacy applications.

Has anyone faced a similar issue before? If yes, then can please provide your inputs.

If not, then can you please provide some trouble-shooting techniques to narrow down to the root cause.

Just for information I have win2k3 servers.

Thanks, Varun

+3  A: 

Wireshark is a great tool for troubleshooting networking code. It'll show you exactly what packets are entering and leaving your network interface in near real time.

As to your specific issue: are you saying that the last chunk of data might be shorter than 64k? If so, your protocol should include some message length information so the receiver knows how much data to look for.

Jim Lewis
A: 

Hi Jim,

I will definitely see how I can use Wireshark to troubleshoot the code. But the problem is I am facing this issue intermittently and that too during a long run only.

Generally recv(), is inside a loop. If the bytes returned by recv is equal to zero, i.e. the buffer is empty, then receiver comes out of the loop. Hence data less than 64k situatuion gets handled.

Thanks, Varun

+1  A: 

A couple of guesses...

If you are using UDP, perhaps one or more packets are being dropped en route (which UDP is permitted to do whenever it feels like). In that case, your receiver might end up waiting for data that is simply never going to arrive; to fix this you would need to either implement some way of automatically resending the lost data, or (if you don't strictly need all the data), some way for the sender to notify the receiver that he is done transmitting, so the receiver might as well stop waiting. (of course you would need to handle the case where this notification gets dropped, as well... it can get complicated if you want 100% robustness)

If you are using TCP, perhaps you are not carefully checking the values returned by send() on the sending side? If you are assuming that send() will always send the number of bytes you asked it to, you might end up thinking send() sent all the bytes when in fact it only sent some (or none) of them... so the sender would think the transmission was complete, while the receiver would be stuck waiting for data that isn't going to arrive.

Jeremy Friesner
A: 

Jeremy,

I am using TCP/IP.

Send() is inside an loop and will keep trying to send the data till it has send all the data.Subtracting each time the bytes sent from the remaining bytes to be sent. Loop terminates when the remaining bytes to be sent becomes zero.

-Varun

A: 

You might have a problem with the server sending data down the wire faster than the receiver is able to read it. You could try increasing the receive buffer:

int nSocketBuffer = 131072; // 128k
if (setsockopt(m_sSocket,SOL_SOCKET,SO_RCVBUF,(LPCSTR)&nSocketBuffer,sizeof(int)) == SOCKET_ERROR)
{
    // socket error
    return false;
}
Alan