Erlang get_tcp:recv数据长度

时间:2011-02-22 17:01:52

标签: sockets erlang

我用户gen_tcp:recv(Socket, 0).进行数据接收,但我一次只能收到1418个字节。如何收到已发送的数据?

1 个答案:

答案 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_tcperl -man gen_tcp的文档中有一个示例。

其他常见格式为asn.1甚至http标头(!)。

技巧

创建一个独立的进程通常是有益的,可以编码和解码您的邮件格式,然后将数据发送到系统的其余部分。通常,Erlang中的一个很好的解决方案是尽可能快地对传入的数据进行解复用,并将数据传递给进程,然后该进程可以处理剩下的问题。