سؤال

I have a non-blocking winsock socket that is recv'ing data in a loop.

I noticed that when connecting with, say, putty and a raw socket, sending messages works just fine. However, when interfacing with this particular client, the packets seem to not be triggering a successful, non-MSG_PEEK call to recv. I recall having a similar issue a few years back and it ended up having to end the packets in \r or something coming from the client, which isn't possible in this case since I cannot modify the client.

Wireshark shows the packets coming through just fine; my server program, however, isn't working quite right.

How would I fix this?

EDIT: Turning the buffer size down to, say, 8 resulted in a few successful calls to recv without MSG_PEEK.

Recv call:

iLen = recv(group->clpClients[cell]->_sock, // I normally call without MSG_PEEK
        group->clpClients[cell]->_cBuff, CAPS_CLIENT_BUFFER_SIZE, MSG_PEEK);
if(iLen != SOCKET_ERROR)
{
    ...

Socket is AF_INET, SOCK_STREAM and IPPROTO_TCP.

هل كانت مفيدة؟

المحلول 2

Use setsockopt to set TCP_NODELAY to TRUE.

نصائح أخرى

Microsoft documentation states in several places that MSG_PEEK should be avoided altogether because it inefficient and inaccurate. Use select(), WSAAsyncSelect(), or WSASelectEvent() instead to detect when a socket has data available for reading, then call recv() to WSARecv() to actually read it.

TCP socket is a stream of bytes, it does not preserve your application message boundaries. As soon as kernel has something to give to you, it returns from the poll. You have to collect received bytes until you have enough to decode whatever you need to decode.

The solution ended up being implementation-specific; I knew the length of all packets coming from the client were divisible by a certain amount of bytes. So, I just read that amount of bytes until the buffer was empty.

The max. number of bytes you can receive at a time in this situation must be less than the maximum length of the longest message, and must be the GCF (Greatest Common Factor) of that length.

This is far from a permanent solution, but it works for now.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top