Boost Asio网络发送/接收是否具有某种形式的数据完整性保证?

时间:2019-06-27 03:45:34

标签: c++ sockets networking tcp boost-asio

我一直在使用boost asio套接字(UDP和TCP)来处理客户端服务器程序之间的自定义协议。一直很好,直到我发现在TCP async_send / async_recieve调用上,数据可以以组合块的形式到达。

例如,如果我用自己的数据包打了两个发送呼叫,它们可以组合成一个接收呼叫。我错误地认为每个发送都对应一个接收,但是我显然是错误的。但是,它在最长的时间内一直运行良好,直到我发现在其他操作系统上运行客户端的问题为止。

所以我的问题是:对于每个接听电话,是否都可以保证到达时数据的完整性? (例如async_send 128字节以128字节的倍数到达,或者必须始终将其到达方式视为随机,例如1字节到达则有127个字节)

更具体地说,这是否意味着:

  • 对于每个发送呼叫,数据可以串联或部分到达,而我 必须始终手动处理串联/部分数据
  • 对于UDP和TCP asio套接字都是这样吗?

我到处搜索,找不到任何文档,所以我想知道是否有人有任何想法。

2 个答案:

答案 0 :(得分:1)

首先重要的是要了解boost asio套接字的接收和发送方法只是意味着它们命令了基础网络堆栈来接收或发送数据。通过网络堆栈,这可能是Windows套接字API。

如果您是通过所谓的环回地址将数据直接发送到同一台计算机,则操作系统(如果有)可以将其“提供”给正在监听的程序,即接收程序。多数民众赞成在这样的情况下,您最幸运的是要让事情井井有条,并在所有情况下始终都能完成。

但是,如果您要寻址另一台计算机或由于操作系统问题,您将有不同的行为:

TCP被设计为可以按发送顺序获取数据。但是,即使在相同的连接上,要发送的块或数据包大小也会有所不同,这是TCP的关键功能。在通知您之前,您的OS或硬件网络适配器可能还会做一些发送或接收缓冲。但是,事情不会丢失。

TCP的简称:您可以通过等待数据async_read_until中的特定点来确保数据完整。来自多个发送呼叫的数据可能在一个接收或多个接收中

与TCP相比,

UDP被设计为具有低延迟,但是没有顺序和完整性保证。因此,当您发送UDP数据报即数据包时,通常OS和网络适配器将尝试尽快将其发送出去。但是,在通往另一台计算机的途中,互联网可能会将其释放,或者将一个数据包保留到您在第一个数据包之后发送之后再发送,这样以后发送的数据就可以稍后再接收,而您也可以先获取发送的数据,以后,也许不会。但是,当您收到数据报时,它本身就是完整的。

所以UDP的简称:数据将以数据报块的形式到达,但是某些数据报可能会丢失,或者以不同于发送的顺序到达。一次发送中的数据可能在一次接收中,也可能不在一次接收中

答案 1 :(得分:-1)

因此,在进行了更多测试之后,我得出了以下结论:答案是否定的。 Boost Asio套接字没有魔术可以强制执行数据完整性,而TCP / UDP协议不能强制执行。

编辑: 因此,这是我的更多研究成果:

For TCP,它就像数据流一样。因此,数据包可能会部分到达或合并到达并且是完整的。因此,用户应用程序需要处理组合或部分数据的反序列化。

For UDP,因为它是一个数据报包,所以如果包到达,则可以保证它是独立且完整的。因此,无需处理部分或组合数据包。