Erlang 网络编程 TCP 和 UDP 消息 v 数据包

Erlang network programming TCP and UDP messages v packets

考虑以下因素:

  {ok, ListenSocket} = gen_tcp:listen(Port, [binary, {packet, 4}, {reuseaddr, true}, {active, once} ]),
  {ok, AcceptSocket} = gen_tcp:accept(ListenSocket),
  receive
    {tcp, Socket, Bin} ->
      case binary_to_term(Bin) of
        {store, Value} ->
          Uid = kvstore:store(Value),
          send(Socket,Uid);
        {retrieve, Key} ->
          send(Socket,kvstore:retrieve(Key))
      end
  end

(发送函数关闭套接字)。

当您为接收方指定 {packet, N} 时,这意味着发送方包含一个 4 字节 big-endian header 指示数据包的长度。 Erlang 运行时读取 header,从一个或多个网络数据包中组装出一条该大小的消息,并针对 active-mode 套接字,将其向上发送到控制进程。 header 不是消息的一部分。

如果您指定 {packet, 4},则邮件大小限制为 2GB(是的,2,不是 4;请参阅 the documentation)。这样的消息不会溢出任何套接字缓冲区,因为消息是由通常较小的底层网络数据包组合而成的。但它对于给定的应用程序来说可能太大了,例如 memory-constrained 嵌入式系统,在这种情况下,人们可能会使用 {packet, 2} 作为协议。

这些陈述也适用于 UDP,但考虑到 UDP 数据包可能会被丢弃或乱序到达,除非应用程序保证整个消息始终适合网络数据包,否则它就没有那么有用了。