# Changing TCP packet format

**URL:** <https://erlangforums.com/t/changing-tcp-packet-format/3629>\
**Category:** Questions / Help\
**Tags:** inet\
**Created:** [May 16, 2024, 2:42pm UTC](https://erlangforums.com/t/changing-tcp-packet-format/3629 "2024-05-16T14:42:58Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![LesserCheese](https://erlangforums.com/letter_avatar_proxy/v4/letter/l/e274bd/32.png) [@LesserCheese](https://erlangforums.com/u/LesserCheese)\
**Post date:** [May 16, 2024, 2:42pm UTC](https://erlangforums.com/t/changing-tcp-packet-format/3629/1 "2024-05-16T14:42:58Z")

</div>

I have to deal with a TCP connection from other software where the format of a “packet” changes. It starts out as text delimited by newline characters but at a certain point needs to change to {packet,4} format, with a 4-byte count followed by binary data, so that I can pass the results of `term_to_binary` reliably.

But when I call `inet:setopts( Socket, [{packet,4}] )` it returns `einval`. Where is this restriction coming from?

---

<div class="post-metadata">

**Author:** ![mmin](https://erlangforums.com/user_avatar/erlangforums.com/mmin/32/2193_2.png) [@mmin](https://erlangforums.com/u/mmin)\
**Post date:** [May 16, 2024, 5:02pm UTC](https://erlangforums.com/t/changing-tcp-packet-format/3629/2 "2024-05-16T17:02:37Z")

</div>

I can’t replicate it:

```erlang
1> {ok, S} = gen_tcp:listen(10000, []).
{ok,#Port<0.4>}
2> inet:setopts(S, [{packet, 4}]).
ok

```

Can you provide more info about `Socket` and any other stuff that could be relevant?

---

<div class="post-metadata">

**Author:** ![LesserCheese](https://erlangforums.com/letter_avatar_proxy/v4/letter/l/e274bd/32.png) [@LesserCheese](https://erlangforums.com/u/LesserCheese)\
**Post date:** [May 16, 2024, 5:39pm UTC](https://erlangforums.com/t/changing-tcp-packet-format/3629/3 "2024-05-16T17:39:28Z")

</div>

The socket was created by `gen_tcp:connect` with options of `[{active,true},{mode,binary},{packet,line}]`. A few lines of ASCII text had been exchanged as part of the protocol and after that the connection becomes just a raw byte stream. Since I want to exchange arbitrary Erlang terms over this channel, the easiest encoding seemed to be `term_to_binary` and then prefix a 4 byte count. I know that I am responsible for adding and stripping the 4 byte header but I figured that setting {packet,4} format would save me the trouble of buffering chunks until I had met the specified length and lower layers would do that.

---

<div class="post-metadata">

**Author:** ![mmin](https://erlangforums.com/user_avatar/erlangforums.com/mmin/32/2193_2.png) [@mmin](https://erlangforums.com/u/mmin)\
**Post date:** [May 16, 2024, 7:52pm UTC](https://erlangforums.com/t/changing-tcp-packet-format/3629/4 "2024-05-16T19:52:38Z")

</div>

I still can’t replicate it:

```erlang
1> {ok, S} = gen_tcp:listen(10000, []).
{ok,#Port<0.4>}
2> {ok, S2} = gen_tcp:connect(#{family=>inet, port=>10000, addr=>{127,0,0,1}}, [{active,true}, {mode, binary}, {packet, line}]).
{ok,#Port<0.5>}
3> gen_tcp:send(S2, <<"some ascii">>).
ok
4> inet:setopts(S2, [{packet, 4}]).
ok

```

What OTP version are you using? Can you provide minimal code sample that causes error?
