数据包有时会被串联 [英] Packets sometimes get concatenated
问题描述
我正在尝试使用Erlang创建一个简单的服务器/应用程序。
我的服务器使用 gen_tcp:listen(Port,[list,{active,false} ,{keepalive,true},{nodelay,true}])
,客户端使用 gen_tcp:connect(Server,Port,[list,{active,true},{ keepalive,true},{nodelay,true}])
。
从服务器收到的消息由诸如 {tcp,_,[115,58 |数据]}
。
问题是,有时数据包在发送或接收时会串联在一起,因此会导致意外行为,因为警卫将下一个数据包视为
有没有办法确保每个数据包都作为一条消息发送到接收进程?
普通TCP是一种没有数据包边界概念的流协议(如Alnitak所说)。
通常,您可以使用成帧协议以UDP(每包大小有限并且可以无序接收)或TCP发送消息。
成帧意味着您为每条消息加上前缀
在erlang中,您可以将{packet,4}添加到套接字选项中以使其成帧TCP上的数据包行为。
假设双方(客户端/服务器)使用{packet,4},那么您只会收到完整的消息。
<注意:您不会看到size标头,erlang会将其从您看到的消息中删除。因此,您在顶部的示例匹配项仍然可以正常工作
I'm trying to make a simple server/application in Erlang.
My server initialize a socket with gen_tcp:listen(Port, [list, {active, false}, {keepalive, true}, {nodelay, true}])
and the clients connect with gen_tcp:connect(Server, Port, [list, {active, true}, {keepalive, true}, {nodelay, true}])
.
Messages received from the server are tested by guards such as {tcp, _, [115, 58 | Data]}
.
Problem is, packets sometimes get concatenated when sent or received and thus cause unexpected behaviors as the guards consider the next packet as part of the variable.
Is there a way to make sure every packet is sent as a single message to the receiving process?
Plain TCP is a streaming protocol with no concept of packet boundaries (like Alnitak said).
Usually, you send messages in either UDP (which has limited per-packet size and can be received out of order) or TCP using a framed protocol.
Framed meaning you prefix each message with a size header (usualy 4 bytes) that indicates how long the message is.
In erlang, you can add {packet,4} to your socket options to get framed packet behavior on top of TCP.
assuming both sides (client/server) use {packet,4} then you will only get whole messages.
note: you won't see the size header, erlang will remove it from the message you see. So your example match at the top should still work just fine
这篇关于数据包有时会被串联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!