【问题标题】:erlang gen_tcp:recv blockerlang gen_tcp:recv 块
【发布时间】:2012-08-14 10:02:57
【问题描述】:

您好,我有这种情况:

gen_tcp:connect(Address, Port, [{buffer, 1024},{active, false},{packet,0},{send_timeout, infinity}]).

我使用gen_tcp:recv(Sock,0),但是来自服务器的消息没有特定的结束模式,所以有什么方法可以防止客户端阻塞recv?

来自文档:

do_recv(Sock, Bs) ->
    case gen_tcp:recv(Sock, 0) of
        {ok, B} ->
            do_recv(Sock, [Bs, B]);
        {error, closed} ->
            {ok, list_to_binary(Bs)}
    end.

【问题讨论】:

    标签: erlang recv gen-tcp


    【解决方案1】:

    首先:拥有一个阻止您知道消息已结束的协议并不是一个好主意。因此,如果您可以控制协议,那么拥有例如附加到您的协议消息的消息长度。

    也就是说,通常最好不要阻止接收。

    我想您希望在等待更多可能稍后到达的数据同时处理来自其他进程的消息时防止阻塞。

    解决方案是使用套接字选项{active, once}

    see description of Erlang socket opts here:

    如果值为一次({active, once}),则来自套接字的一条数据消息将发送到进程。要接收更多消息,必须使用 {active, once} 选项再次调用 setopts/2

    您可能想使用{active, true} 并获取每个数据的消息。这样做的问题是您没有流量控制,因此如果您被数据淹没,VM 会立即读取所有内容并填充到您的消息邮箱中。这很快就会失控,因为不断增长的邮箱会减慢您的速度,并且可能会吃掉您所有的记忆。

    使用{active, once} 可避免此消息泛滥。

    也可以在Learn You Some Erlang: More Control With Inet找到一个很好的描述

    【讨论】:

    • 感谢同行,我应该用什么代替 recv 来保存回复?在示例中,他们使用了 flush() 但我无法从那里保存消息,或者不?
    • 如果您现在还没有遇到“receive”语句以及 Erlang 消息是如何工作的,那么您已经遥遥领先了。最好从头开始“Learn You Some Erlang”。如果你跳过“简单”的部分,你将很难使用 Erlang。消息发送和接收以及模式匹配对于使用 Erlang 非常重要
    猜你喜欢
    • 2011-04-16
    • 2023-04-07
    • 2011-02-09
    • 1970-01-01
    • 2016-08-01
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    相关资源
    最近更新 更多