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
(发送函数关闭套接字)。
- 我假设 EVM 负责重建组成消息的 n 数据包,而不是用户代码?
- 在什么情况下会有很大的消息溢出套接字缓冲区的风险?
- 这些陈述是否同样适用于 UDP?
当您为接收方指定 {packet, N}
时,这意味着发送方包含一个 4 字节 big-endian header 指示数据包的长度。 Erlang 运行时读取 header,从一个或多个网络数据包中组装出一条该大小的消息,并针对 active-mode 套接字,将其向上发送到控制进程。 header 不是消息的一部分。
如果您指定 {packet, 4}
,则邮件大小限制为 2GB(是的,2,不是 4;请参阅 the documentation)。这样的消息不会溢出任何套接字缓冲区,因为消息是由通常较小的底层网络数据包组合而成的。但它对于给定的应用程序来说可能太大了,例如 memory-constrained 嵌入式系统,在这种情况下,人们可能会使用 {packet, 2}
作为协议。
这些陈述也适用于 UDP,但考虑到 UDP 数据包可能会被丢弃或乱序到达,除非应用程序保证整个消息始终适合网络数据包,否则它就没有那么有用了。
考虑以下因素:
{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
(发送函数关闭套接字)。
- 我假设 EVM 负责重建组成消息的 n 数据包,而不是用户代码?
- 在什么情况下会有很大的消息溢出套接字缓冲区的风险?
- 这些陈述是否同样适用于 UDP?
当您为接收方指定 {packet, N}
时,这意味着发送方包含一个 4 字节 big-endian header 指示数据包的长度。 Erlang 运行时读取 header,从一个或多个网络数据包中组装出一条该大小的消息,并针对 active-mode 套接字,将其向上发送到控制进程。 header 不是消息的一部分。
如果您指定 {packet, 4}
,则邮件大小限制为 2GB(是的,2,不是 4;请参阅 the documentation)。这样的消息不会溢出任何套接字缓冲区,因为消息是由通常较小的底层网络数据包组合而成的。但它对于给定的应用程序来说可能太大了,例如 memory-constrained 嵌入式系统,在这种情况下,人们可能会使用 {packet, 2}
作为协议。
这些陈述也适用于 UDP,但考虑到 UDP 数据包可能会被丢弃或乱序到达,除非应用程序保证整个消息始终适合网络数据包,否则它就没有那么有用了。