Erlang gen_tcp: recv (Socket, Length) semantics

After reading this answer , I want to understand that the same thing applies to calls gen_tcp:recv(Socket, Length). My understanding of the documentation is that if more than Lengthbytes are available in the buffer , they stay there; if the number of bytes is less Length, call blocks until it is available or the connection is closed.

In particular, this should work when packets have a prefix with two bytes containing the length of the packet in numerical order:

receive_packet(Socket) ->
  {ok, <<Length:16/integer-little>>} = gen_tcp:recv(Socket, 2),
  gen_tcp:recv(Socket, Length).

It is right?

+1
source share
1 answer

Yes (or No, see comments for details).

Consider:

Shell 1:

1> {ok, L} = gen_tcp:listen(8080, [binary, {packet, 0}, {active, false}]).
{ok,#Port<0.506>}
2> {ok, C} = gen_tcp:accept(L). %% Blocks
...

Shell 2:

1> {ok, S} = gen_tcp:connect("localhost", 8080, [binary, {packet, 0}]).
{ok,#Port<0.516>}
2> gen_tcp:send(S, <<0,2,72,105>>).
ok
3>

Shell 1 continued:

...
{ok,#Port<0.512>}
3> {ok, <<Len:16/integer>>} = gen_tcp:recv(C, 2).
{ok,<<0,2>>}
4> Len.
2
5> {ok, Data} = gen_tcp:recv(C, Len).
{ok,<<"Hi">>}
6>

, . {packet, N}, , ( ).

, , ( = 2 1):

Shell 1:

1> {ok, L} = gen_tcp:listen(8080, [binary, {packet, 2}, {active, false}]).
{ok,#Port<0.506>}
2> {ok, C} = gen_tcp:accept(L). %% Blocks
...

Erlang 2 , recv/2 , . 0 recv/2.

Shell 2:

1> {ok, S} = gen_tcp:connect("localhost", 8080, [binary, {packet, 0}]).
{ok,#Port<0.516>}
2> gen_tcp:send(S, <<0,2,72,105>>).
ok
3>

Shell 1:

...
{ok,#Port<0.512>}
3> {ok, Data} = gen_tcp:recv(C, 0).
{ok,<<"Hi">>}

{packet, N} 2, , 0. packet , gen_tcp / .

0, recv/2 >= 0, , C. , - {, } .

: http://www.erlang.org/doc/man/gen_tcp.html http://www.erlang.org/doc/man/inet.html#setopts-2

, .

+3

Source: https://habr.com/ru/post/1677184/


All Articles