Myles McDonnell
Myles McDonnell

Reputation: 13335

Erlang network programming TCP and UDP messages v packets

Consider the following:

  {ok, ListenSocket} = gen_tcp:listen(Port, [binary, {packet, 4}, {reuseaddr, true}, {active, once} ]),
  {ok, AcceptSocket} = gen_tcp:accept(ListenSocket),
  receive
    {tcp, Socket, Bin} ->
      case binary_to_term(Bin) of
        {store, Value} ->
          Uid = kvstore:store(Value),
          send(Socket,Uid);
        {retrieve, Key} ->
          send(Socket,kvstore:retrieve(Key))
      end
  end

(The send fun closes the socket).

Upvotes: 0

Views: 441

Answers (1)

Steve Vinoski
Steve Vinoski

Reputation: 20024

When you specify {packet, N} for a receiver it means the sender includes a 4-byte big-endian header indicating the length of the packet. The Erlang runtime reads that header, assembles a message of that size from one or more network packets, and for an active-mode socket, sends it up to the controlling process. The header is not part of the message.

If you specify {packet, 4} then the message size is limited to 2GB (yes, 2, not 4; see the documentation). Such a message won't overflow any socket buffer since the message is assembled from underlying network packets which are normally smaller. But it might be too large for a given application, such as a memory-constrained embedded system, in which case one might use {packet, 2} for the protocol instead.

These statements are also true for UDP, but given that UDP packets can be dropped or arrive out of order, it's not as useful unless the application guarantees that whole messages always fit within network packets.

Upvotes: 3

Related Questions