【问题标题】:Receiving unknown strings lengths?接收未知的字符串长度?
【发布时间】:2015-04-27 20:41:54
【问题描述】:

所以我正在将我编写的 Python 程序转换为 Erlang,而我已经很久没有使用 Erlang 了。所以我客人我回到了初学者的水平。无论如何,从经验来看,我在处理套接字时使用的每种语言都有发送/接收函数,这些函数总是返回发送/接收数据的长度。然而,在 Erlangs gen_tcp 的情况下似乎并没有这样做。

所以当我调用 send/recv/或 inet:setopts 时,它知道数据包何时结束?我是否需要编写一个循环的 recvAll/sendAll 函数,以便在我希望接收的数据包(字符串)中找到转义符或 \n?

http://erlang.org/doc/man/gen_tcp.html#recv-2

我正在使用的示例代码:

server(LS) ->
    case gen_tcp:accept(LS) of
        {ok,S} ->
            loop(S),
            server(LS);
        Other ->
            io:format("accept returned ~w - goodbye!~n",[Other]),
            ok
    end.

loop(S) ->
    inet:setopts(S,[{active,once}]),
    receive
        {tcp,S,Data} ->
            Answer = process(Data), % Not implemented in this example
            gen_tcp:send(S,Answer),
            loop(S);
        {tcp_closed,S} ->
            io:format("Socket ~w closed [~w]~n",[S,self()]),
            ok
    end.

仅通过查看示例和文档,Erlang 似乎就知道了。我想确认一下,因为接收到的数据长度可以在 20 字节到 9216 字节之间,或者可以分块发送,因为客户端是我正在编写的 PHP 套接字库。

谢谢,

Ajm。

【问题讨论】:

标签: sockets erlang gen-tcp


【解决方案1】:

TL;DR

所以当我调用 send/recv/或 inet:setopts 时,它知道数据包何时收到 结束了吗?

不,它没有。

我是否需要编写一个循环的 recvAll/sendAll 函数以便我可以找到 我希望接收的数据包(字符串)中的转义符或\n?

是的,一般来说,你会的。但是 erlang 可以为您完成这项工作。

怎么做?

实际上,在将消息拆分为数据包的意义上,您不能依赖 TCP。通常,TCP 会将您的流拆分为任意大小的块,您的程序必须组装这些块并自己解析此流。因此,首先,您的协议必须是“自定界”的。例如,您可以:

  1. 在二进制协议中 - 在每个数据包之前加上其长度(固定大小字段)。因此,协议框架将如下所示:<<PacketLength:2/big-unsigned-integer, Packet/binary>>
  2. 在文本协议中 - 以换行符号结束每一行。

Erlang 可以帮助您完成这笔交易。看看这里http://erlang.org/doc/man/gen_tcp.html#type-option。有一个重要的选项:

{packet, PacketType}(TCP/IP sockets)

Defines the type of packets to use for a socket. The following values are valid:

raw | 0

    No packaging is done.
1 | 2 | 4

    Packets consist of a header specifying the number of bytes in the packet, followed by that number of bytes. The length of header can be one, two, or four bytes; containing an unsigned integer in big-endian byte order. Each send operation will generate the header, and the header will be stripped off on each receive operation.

    In current implementation the 4-byte header is limited to 2Gb.

line

    Line mode, a packet is a line terminated with newline, lines longer than the receive buffer are truncated.

最后一个选项 (line) 对您来说最有趣。如果您设置此选项,erlang 将在内部解析输入流并输出按行拆分的数据包。

【讨论】:

    猜你喜欢
    • 2016-07-19
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    相关资源
    最近更新 更多