我知道有可能将多个数据包堆叠到要读取的缓冲区,并且长数据包可能需要完全发送多个发送尝试的循环。但在这些情况下,我对包装有疑问:
当我想到网络套接字包装时,我想到了这些问题。特殊字符用于标记数据包的开头和结尾,这可以得出结论:不可能将多个包分开。
P.S。所有问题都与TCP / IP有关,但欢迎您分享有关UDP的信息(答案)。
答案 0 :(得分:2)
TCP套接字是基于流的。订单是有保证的,但每次recv / read接收的字节数可以是发送方的任何待处理字节块。您可以通过添加成帧信息来在TCP之上对基于消息的传输进行分层,以指示有效负载应该分组到消息中的方式。这就是WebSockets的功能。每个WebSocket消息/帧以至少2个字节的头信息开始,该信息包含要遵循的有效载荷的长度。这允许接收器等待并重新组装完整的消息。
例如,实现标准Websocket API或类似API(例如浏览器)的库/接口,onmessage事件将针对收到的每条消息触发一次,并且事件的data属性将包含整个信息。
请注意,在较旧的Hixie版本的WebSockets中,每个帧都以'\ x00'开头,并以'\ xff'结尾。当前标准化的IETF 6455(HyBi)版本的协议使用包含长度的标头信息,这允许更容易处理帧(但请注意,旧的和新的仍然是基于消息的并且具有基本相同的API)。 / p>
答案 1 :(得分:1)
TCP连接提供字节流,因此请将其视为此类。不保留应用程序消息边界 - 一个发送可以对应多个接收,反之亦然。你需要两边都有循环。
另一方面,UDP是基于数据报(即消息)的。这里一次读取将始终使单个数据报出列(除非你在插槽上弄乱低级别标志)。如果您的应用程序缓冲区小于挂起的数据报,并且您只读取其中的一部分,则其余部分将丢失。解决这个问题的方法是将发送的数据报的大小限制在普通MTU值1500以下(更少的IP和UDP报头,实际上是1472)。