Packets are mixing in socket's queue

Hello everyone,
Iam so tired from triying understanding what’s going into my program, I have a gen_statem server and a gen_statem client that should communicate, first the client send some data to the server and waits for a response, the code looks :

%%%%%%  client side  %%%%%%
....
gen_tcp:send(Socket, BinData),
Res = waiting_reponse(Socket),
....
waiting_response(Socket)  ->
receive
      {tcp, Socket, Data}  ->
                Data
end.
....
%%%%%%  server side  %%%%%%
....
some_state(info, {tcp, Socket, Bin}, Data) ->
....
%%%%  some handling
gen_tcp:send(Socket, Data1),
....
gen_tcp:send(Socket, Data2)
....

The problem is that the client receive Data1 and Data2 combined in one {tcp, Socket, Data} message, why ?
I tried a small other program between client and server and with the same previous Socket Options and packets never have been mixed together so I just want to know what is that ?

1 Like

TCP is a byte-oriented protocol. Between a client and a server the data is transmitted as a stream of bytes, and there’s no guarantee about how those bytes are packaged in packets during transmission. Therefore it is quite natural to see that messages sent by a client are consolidated by the network stack in one larger packet.

3 Likes

Indeed!

@Abdelghani
Plain TCP doesn’t know about packets. The data you are sending is probably small so it gets cached and sent as an one TCP frame.
The solution to this is to introduce some kind of package header so that the receiving side can know which data corresponds to which packet. Luckily for you, you can do this pretty easy with erlang, by specifying option {packet, 1 | 2 | 4} which will add 1/2/4 byte header so the receiving TCP stack will separate those packets. This option must be set on both client and server. For more info on packaging possibilites read Erlang -- inet .

3 Likes

@mmin consider we set {packet, 4} as a socket option and the server send 3 packets to the client, how many {tcp, Socket, Data} messages the client will receive ? 1 or 3 ?

According to doc should be 3. Set this option on both client and server sockets and see what happens.

1 Like

exactly I will try it later thank you @mmin

1 Like