3

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

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、硬件?

谢谢。

4

1 回答 1

2

您可能将接收缓冲区设置得太小。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 XI 上,默认接收缓冲区大小约为 512Kb。


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

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

于 2011-02-19T01:58:53.807 回答