1

Is there any way to differentiate payloads from different packets while using blocking function read in c programming? I'm sending each message in a packet from TCP client and when i read(using read function) it in a TCP server i get all message together in a buffer without any delimiter in between.

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
Govindh
  • 67
  • 1
  • 10
  • 3
    TCP is stream-oriented. There are no packets as far as your application is concerned, only an uninterrupted stream of bytes. Packets at the lower levels of the protocol can be split and merged by any intermediate party at will, so it would be meaningless to look at them. – n. m. could be an AI Dec 15 '16 at 06:21

2 Answers2

4

You will have to implement that yourself on application layer.

One approach is for example Type-Length-Value.

Each message you send has following structure:

1 byte | 2 byte | length bytes
type    length   value

More details here.

Beware that read doesn't read exactly the number of bytes specified, it can read fewer - so you need to check its return value. For example see this.

There are also some gotchas with binary protocols you may want to be aware of.

Also it is advisable you do some background reading on network programming, e.g. here - see chapter 7.

Community
  • 1
  • 1
Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
  • If the client is something like PUTTY or telnet is there any way to do it? – Govindh Dec 15 '16 at 06:18
  • @Govindh You have to put the delimiter there, none will do if for you. – Giorgi Moniava Dec 15 '16 at 06:19
  • T-L-V is the preferred approach for this task. If you are working with third party tools they might have T-L-V or might use some sort of delimiter to convey end of message. This is required since TCP is a byte stream protocol without any inherent message boundaries. Telnet i guess using CR LF delimiter (http://www.freesoft.org/CIE/RFC/1123/31.htm) – A.N Dec 15 '16 at 06:23
  • There is no concept of packet boundaries in TCP. The packet boundaries are defined by application layer. So you need to study how the application is defining the packet boundary. For e.g. A simple server might define a packet as a combination of 3 fields as in Tag-Length-Value so you can first read the 1 byte tag, then the length and then actual data i.e. length bytes long. – A.N Dec 15 '16 at 06:26
  • putty is just an application. What protocol are you using inside putty? – A.N Dec 15 '16 at 06:32
  • @A.N: "*protocol ... inside PuTTY*" Err, what are you after? – alk Dec 15 '16 at 10:51
  • @alk what I meant is putty is just a client for telnet, ssh. The packets on wire can vary for telnet, ssh protocol and are not the same. – A.N Dec 15 '16 at 10:56
3

TCP is stream oriented, which means that there is no packets which you could separate them, So you have to implement your protocol, for example you can send 4 bytes of header data before sending each packet and tell the receiver next packet size, in the receiving side you should always read a 4 byte header (which identifies next packet size) and make a blocking read with size specified in header.

Another option is to use fixed size packets, so every time you have to read fixed size packet from TCP buffer.

Unlike TCP, UDP is packet oriented, just as you want. in UDP packets are received in the size of sent and no other buffering or concatenations will happen, but its unreliable.

e.jahandar
  • 1,715
  • 12
  • 30