× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



You are using TCP, which is a stream socket (SOCK_STREAM). The data is not organized into fixed-length chunks, it's organized into a continuous stream of data.

Just because the other end sent 1869 bytes does not (and SHOULD NOT) mean that you will receive 1869 bytes when you call recv(). It means that 1869 bytes have been sent from the other application to that other computer's TCP/IP stack.

You might receive 500 bytes, then 1000 bytes, then 369 bytes. Or you might receive 10 bytes, then 1859 bytes. Or you might receive any other variation of calls that add up to 1869.

Furthermore, if the sender sends 1869 in one call, followed by 1000 in the second call, it's possible that your application will receive 2869 in a single call to recv().

Don't write your application in a manner that expects data to arrive in a fixed-length chunk. That's not how TCP was intended to work! Think of the data as a continuous stream, depending on the speed of the computer, how busy it is, how fast the network is, etc, you will receive different lengths at different times. It's no big deal, just call recv() in a loop until you get the total size you need.

If you really, really, want to force the TCP stream to only return data when 1869 bytes are available, then you should set the SO_RCVLOWAT socket option to 1869. But I discourage you from doing this, because IMHO, it's not the right mindset. A stream socket (SOCK_STREAM) is just that -- a continuous stream of data. It's not a record-oriented service, don't treat it like a record-oriented service. Plus, if you set SO_RCVLOWAT and the sender sends a shorter amount of data, you're stuck blocking on that socket waiting for the rest of the data, which isn't good either.

I strongly recommend that you design your TCP communications to use some sort of a delimiter instead of using a fixed-length piece of data. Most TCP applications use CRLF as a delimiter, so that the data appears on the display like normal text, it makes it much easier to troubleshoot your applications.

Alternately, send the length first, followed by the data, so that the receiving side knows exactly how many bytes it can expect, and can loop until it's received the whole thing. This is the way HTTP (and others) transfer data so that no special delimiter character has to be chosen (and therefore, no escaping of special characters is needed)

I wrote an article that demonstrates how to use a loop to receive a fixed-length chunk of data from a stream socket. The following link requires a membership to System iNetwork, but a free ("Associate") membership will work fine:
http://www.systeminetwork.com/article.cfm?id=51985


GKern@xxxxxxxxxxxxxxxx wrote:
I have a socket server program. The client is sending 1869 bytes of data, but the socket Read function only returns 1392 bytes, and on the subsequent read it returns the remaining 477 bytes (1392+477=1869).

When I look at the TCP connection status via netstat *cnn I can see Bytes In listed as 1869 but then paging down I see the Maximum Segment Size is 1392.

I've tried to use the set socket option for SO_RCVBUF to override the number of bytes per socket read.

Funny thing is that if I disconnect the client, and re-issue the Socket Accept to create a new socket, and then reconnect and resend the 1869 bytes, I get all 1869 bytes in one read. But then if I resend the same data again it reverts back to the original problem (1392 bytes read first time and subsequent 477 bytes read the second time).

How can I correct this so that I can in one read accept the entire string of data sent by the client?

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.