Character delimited packets?

Started by
37 comments, last by ANSI2000 21 years, 5 months ago
I have an application that has creates one persistant TCP/IP connection to a server application. Unfortunantly the server application was written many years ago and it only allows one connection from the client computer... That said... Now my application has an internal queue, once the queue has a message it is sends out to the server application. Now if my application sent out 5 messages, the server will not return them in the same order they where sent in, which is ok because the messages have an id within them to be identified... Note: The messages are sent out one after the other since I use synchronus sockets and send() is called once for every message... Now the question is when my application receives back the responses for those messages... My receive loop has been programmed to look for a specific character once it finds that caharcter it assumes the message is complete. The issue is if the server responds back with more then 1 message is it possible that the packets of those messages get intertwinted, like recives 5 bytes from one message another 10 from the other etc...? Or will TCP/IP make sure at least that all the packets fro one message go through before the other message comes in...
Advertisement
quote:
Now if my application sent out 5 messages, the server will not return them in the same order they where sent in

If you''re using TCP, then the messasges are guaranteed to arrive in the same order as they are sent. That''s because TCP is a stream based protocol, and have no sense of packets.
quote:
The issue is if the server responds back with more then 1 message is it possible that the packets of those messages get intertwinted, like recives 5 bytes from one message another 10 from the other etc...? Or will TCP/IP make sure at least that all the packets fro one message go through before the other message comes in...

As said above, TCP is stream based, and has no sense of individual packets (nor start or beginning if them). If you send two (or more) packets directly after each other, the sending computer may even put them in one single message before sending them. That''s because there are no real packets, but a stream of bytes.

I get the impression that you lack one important feature: a header. You said you send an ID along with the message to identify it. That''s great. When extracting the information, it''s really good to know how many bytes to expect. That''s what the header is for; to send information to descibe what''s comming. For example, your header could look something like this.

  struct my_header{    short ID;    short length;};  

Fill in the structure with proper ID and the length of the data to send, and then send it along with the data. Before the data that is. When receiving, just extract the header, and read the length-field to see how many bytes the message consists of.
That the problem this protocol doesn''t work with a header it works as character delimited. If I were to put a header infront of the message the receiving server would not recognize the format anymore. Now I canot tell a bank change your format!

Also when I say send several "messages" one after the other, the server on the other side doesnt guarantee that the responses will come back in the same order. So If sent messages 1,2,3,4,5 I might get them back as 5,2,3,1,4. This is not at the packet level...

Now the problem is, if the server sends back to me 2 "mesages" and tcp/ip splits the messages in 2 packets where the entire first message is the the first packet and a few bytes of the seconds message are also included in the first packet, then in the second packet is the rest of the second message how would I handle that?

Rember the protocol is character delimited...

An easier question would be...

If I do the following in my code...

send(sock, "hello", ....);
send(sock, " world", ...);

will tcp/ip append bytes of buff2 to the packet of buff1?
Is it possible the server on the other side might receive "hello wo" and "rld"or will tcp/ip at least make sure that "hello" get there first and then "world"?

quote:
If I do the following in my code...

send(sock, "hello", ....);
send(sock, " world", ...);

will tcp/ip append bytes of buff2 to the packet of buff1?

It will send what you tell it to send. No more, no less. If you tell it to send the ten letters H, E, L, L, O, W, O, R, L and D (in that specific order), then it will do so, without any modifications what so ever.

Remember what I said above, TCP does not work with messages, it's a stream based protocol. The receiver will receive the buffer "helloworld" as if it were a small part of a huge buffer. There are no such thing as "packets" in TCP. If you want to split the string in two, you have to provide a mechanist to do so yourself, cause TCP won't help you. Either use a header as mentioned above (which I understand now is out of the question, but in general), or send an extra delimiter similar to a null terminator.

Just by sending two buffers like that, without any header or delimiter, or anything else to identify the two strings, won't work.

[edited by - Brother Bob on October 17, 2002 4:59:37 PM]
Ok fine but am saying if do the 2 sends one after the other like shown previously...

Will recv for example retun "hello wo", which then requires a second call to recv to get the rest of the stream "rld"

[edited by - ANSI2000 on October 17, 2002 5:15:00 PM]
quote:Original post by ANSI2000
Ok fine but am saying if do the 2 sends one after the other like shown previously...

Will recv for example retun "hello wo", which then requires a second call to recv to get the rest of the stream "rld"


Recv will return as many bytes as have gotten across the network so far. That could be one string, both strings, or perhaps even one byte per recv.

You need to check the size returned by recv and do the right thing.
This question comes up literally every week. With TCP forget the word "packet". There is no such thing. You''re "Hello world" could arrive as:

"Hello "-"world" or
"He"-"llo world" or
"Hello worl"-"d" or
"H"-"e"-"l"-"l"-"o"-" "-"w"-"o"-"r"-"l"-"d"

or as any other permutation you could think of *regardless* of how many sends you did originally. You need to be prepared to buffer partial messages and handle multiple messages arriving in a single recv.

-Mike
-Mike
wow, that screws all my network code, yippy.....

--Fireking

Owner/Leader
Genetics 3rd Dimension Development
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
wait, does this apply to non-blocking servers?

my server uses select() to find out if any data needs to be recv''d, then i recv() it.

--Fireking

Owner/Leader
Genetics 3rd Dimension Development
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
Non-blocking sockets have the same problem.

All select tells you is that some data has been received, it could be 1 byte or 1000. You won''t know until you check the value returned by recv().

This topic is closed to new replies.

Advertisement