我用户gen_tcp:recv(Socket, 0).
进行数据接收,但我一次只能收到1418个字节。如何收到已发送的数据?
答案 0 :(得分:7)
在gen_tcp:recv(Socket, 0)
中你问内核:“给我现在在接收缓冲区中可用的所有数据”。然而,内核也可以免费给你。即使是相当快速的链接,您也可能会在TCP连接上点击 slow start ,因此在开始时您将无法获得太多数据。
解决方案是做自己的缓冲。您必须从底层套接字中获取数据,直到您有足够的数据来构造消息。由于这个原因,二进制协议在流上实现它们自己的消息传递是很常见的。
对于长期记录:常见的消息格式是将消息编码为:
decode(Bin) when is_binary(Bin) ->
<<Len:32/integer, R/binary>> = Bin,
<<Payload:Len/binary, Remain/binary>>,
{msg, {Len, Payload}, Remaining}.
即,消息是4个字节,表示32位bigendian整数,后跟有效负载,其中长度由整数给出。这种格式和其他类似的格式非常常见Erlang包含直接在C层中的优化解析器。要访问这些内容,请通过inet/setops/2
在套接字上设置选项,在我们的示例中,我们设置{packet, 4}
。然后我们可以通过在套接字上设置{active, once}
来获取消息并等待下一条消息。当它到达时,我们可以再次{active, once}
在套接字上获取下一条消息,依此类推。如果您正确安装了Erlang手册页,gen_tcp
(erl -man gen_tcp
的文档中有一个示例。
其他常见格式为asn.1甚至http标头(!)。
创建一个独立的进程通常是有益的,可以编码和解码您的邮件格式,然后将数据发送到系统的其余部分。通常,Erlang中的一个很好的解决方案是尽可能快地对传入的数据进行解复用,并将数据传递给进程,然后该进程可以处理剩下的问题。