发送和接收套接字(TCP / IP)

时间:2012-03-01 21:05:24

标签: sockets tcp websocket

我知道有可能将多个数据包堆叠到要读取的缓冲区,并且长数据包可能需要完全发送多个发送尝试的循环。但在这些情况下,我对包装有疑问:

  1. 当有多个正在等待读取的数据包时,如果我调用 recv (或任何替代(低级别)函数),它是否会将它们全部堆叠到我的缓冲区中或只返回其中一个(如果我的缓冲区不足,还是第一个的一部分?)
  2. 如果我发送一个需要多次迭代才能完全发送的长数据包,它会计为单个数据包还是多个数据包?这基本上是一个问题,它是否标志着发送的包裹未满?
  3. 当我想到网络套接字包装时,我想到了这些问题。特殊字符用于标记数据包的开头和结尾,这可以得出结论:不可能将多个包分开。

    P.S。所有问题都与TCP / IP有关,但欢迎您分享有关UDP的信息(答案)。

2 个答案:

答案 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)。