Reputation: 1745
I am writing erlang tcp-server which runs following protocol.
<<?SPECIAL_BYTE, 0, PayloadLength:2/big-unsigned-integer-unit:8>>
. This packet indicates, that server must read next PayloadLength
bytes of raw data.I can receive raw stream of data and parse this protocol in erlang code, of course. But I wonder, is there any way to use builtin erlang packet packaging? When my packets preceded with its length, I can say [{packet, HeaderLength}]. Is there any way to force erlang to automatically package received data by 4-bytes chuks?
UPD: I am planning to use {active, once} mode. Also I can use gen_tcp:recv(Socket, 4), but I afraid performance penalty due multiple socket reads in this case. Is my fear justified?
Upvotes: 3
Views: 803
Reputation: 6347
Erlang's native packet decoding is extremely helpful, when it matches the actual format of your data. If your packets are always encoded with a 4 bytes (32 bits) big-endian length, then {packet, 4}
is exactly what you need. However, if there are some exceptions in your encoding, then you must use {packet, raw}
and do the decoding yourself.
For the decoding, you can indeed use the socket in passive mode witb {active, false}
, read four bytes and then the rest of the packet. You can also use the socket in active mode, but in this case you must be prepared to receive less or more than your packet header, including more than a single packet. {active, once}
can help but will not solve the problem. Passive mode might be easier to deal with in your case.
Performance-wise, you can refer to the following question: How can the "packet" option of socket in Erlang accelerate the tcp transmission so much? However, I highly suggest to focus on getting a working implementation before trying to optimize it. Premature optimization never yields good results.
Upvotes: 2