【问题标题】:limitation of the reception buffer接收缓冲区的限制
【发布时间】:2011-06-15 09:16:54
【问题描述】:

我通过这种方式与客户建立了连接:

gen_tcp:listen(1234,[binary,{packet,0},{reuseaddr,true},{active,false},{recbuf,2048}]).

此代码执行消息处理:

loop(Socket)->
    inet:setops(Socket,[{active,once}],
    receive
        {tcp,Socket,Data}->
            handle(Data),
            loop(Socket);
        {Pid,Cmd}->
            gen_tcp:send(Socket,Cmd),
            loop(Socket);
        {tcp_close,Socket}->
            % ...
end.

我的操作系统是 Windows。当消息的大小为 1024 字节时,我会丢失 Data 中的字节。服务器向客户端发送ACK+FIN。

我认为 Erlang 限制为 1024 字节,因此我定义了recbuf

问题出在哪里:Erlang、Windows、硬件?

谢谢。

【问题讨论】:

  • 真的不知道问题所在?
  • 我不是 Erlang 人,所以不能真正理解你在做什么。究竟是什么问题?

标签: sockets networking erlang erlang-otp


【解决方案1】:

您可能将接收缓冲区设置得太小。 Erlang 当然不限于 1024 字节的缓冲区。您可以通过在 shell 中执行以下操作来检查自己:

{ok, S} = gen_tcp:connect("www.google.com", 80, [{active,false}]),
O = inet:getopts(S, [recbuf]),
gen_tcp:close(S),
O.

在 Mac OS X 上,我的默认接收缓冲区大小约为 512Kb。


使用{packet, 0} 解析,您将收到网络堆栈选择发送的任何块中的 tcp 数据,因此您必须自己进行消息边界解析和缓冲。您是否有可靠的方法来检查有线协议中的消息边界?如果是这样,接收 tcp 数据并将其附加到缓冲区变量,直到您有完整的消息。然后在完整消息上调用句柄并在继续之前从缓冲区中删除完整消息。

如果您向我们提供有关客户端和使用的协议的一些信息,我们可能会为您提供更多帮助。

【讨论】:

  • 感谢您的解释。不幸的是我没有任何信息(我尝试反向工程方法)。客户端发送一条或多条由 分隔的消息。问题是“几个”!因此我没有完成缓冲的标准。
  • 所以你有一个消息边界标记'\r\n'?如果是这样,那么 Erlang 内置了解决方案 - 在监听选项中使用 {packet, line} 让 Erlang 为您缓冲整行。然后根据需要处理来自套接字的尽可能多的行消息,或者处理直到收到套接字关闭消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-11
  • 2012-12-05
  • 2014-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多