是(或否,详见 cmets)。
考虑:
外壳 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
...
外壳 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>
外壳 1 续:
...
{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} 选项来定义数据包长度应该有多少字节(在大端系统上)。
与之前相同,但没有显式提取长度(注意 shell 1 中的数据包长度 = 2):
外壳 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 将阻塞直到它需要的字节数。在这种情况下,recv/2 中的读取长度必须为 0。
外壳 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>
外壳 1:
...
{ok,#Port<0.512>}
3> {ok, Data} = gen_tcp:recv(C, 0).
{ok,<<"Hi">>}
在这种情况下,我没有在 shell 2 中指定 {packet, N} 选项只是为了展示这个想法,但通常它不是 0。如果设置了 packet 选项,那么 gen_tcp 将自动附加/删除那么多包中的字节数。
如果您指定数据包 0,那么您必须执行长度 >= 0 的recv/2,其行为与 C 中的行为相同。您可以通过在执行接收和在这种情况下,这将返回 {error, timeout}。
更多信息可以在这里阅读:
http://www.erlang.org/doc/man/gen_tcp.html
http://www.erlang.org/doc/man/inet.html#setopts-2
希望这能解决问题。