有两种类型的碎片:IP级碎片和DDS级碎片。
当传输层(通常是UDP或TCP)提供的有效载荷超过适合链路帧的最大有效载荷大小(也称为链路最大传输单元或链路MTU)时,就会发生IP级碎片。如果网络是以太网,则链路MTU是以太网帧的最大大小。当接收器NIC获得IP片段时,它会将它们存储在缓冲区中,直到接收到所有片段,并且可以重新组装以形成UDP数据报或TCP段。当接收到所有片段时,执行重新组装,并将消息提供给应用层。
如果您尝试发送一个大小大于MTU的DDS样本,但尚未设置DDS级碎片,您将看到IP级碎片。众所周知,IP级碎片是脆弱的,如果您的系统配置不正确,可能会导致通信问题。例如,当您的应用程序依赖于传输来对数据进行分片,并且一个分片丢失时,则需要重新发送所有分片以修复丢失的分片——而如果您使用Reliable reliability(见7.5.21 reliability QosPolicy),Connext DDS可以修复单个丢失的DDS分片。
23.3.3异步发布
如果您使用的是Reliable 7.5.21 RELIABILITY QosPolicy,DDS级碎片需要异步发布。发送大于传输的message_size_max的可靠样本需要异步发布,这样碎片化过程就可以在编写样本的线程的上下文之外进行。
如果您使用的是尽力而为的可靠性,则大于message_size_max的样本将被分割;但是,不建议使用此配置(尽力而为,加上碎片化),因为您更有可能丢弃样本。错误“COMMENDSrWriterService_on_Submessage:!write-resend。可靠的大数据需要异步写入”来自序列化样本大于传输的message_size_max,而7.5.21可靠性QOS策略设置为可靠性QOS,但未启用异步发布。
要在使用可靠可靠性的同时对DDS数据包进行分段,请将7.5.20 PUBLISH_MODE QosPolicy(DDS扩展)中的kind设置为ASYNCRONOUS_PUBLISH_MODE_QOS。使用这些设置,Connext DDS将使用单独的线程发送片段。这将减轻应用程序线程执行碎片和发送工作的负担。有关异步发布器的更多信息,请参阅7.4.1异步发布器QoS策略(DDS扩展)。
可能还需要将内置PublicationBuiltinTopicData和SubscriptionBuiltinTopDataWriters的发布模式设置为异步。这是通过9.5.3 DISCOVERY_CONFIG QoS策略(DDS扩展)完成的(详见23.3.5示例)。PublicationBuiltingTopicData或SubscriptionBuiltnTopicData样本较大的最常见原因是序列化的TypeCode或TypeObject,但您也可能发送了大量属性(通过7.5.19 PROPERTY QosPolicy(DDS扩展))或具有较大的ContentFilteredTopic筛选器表达式,以及其他大小可变的字段,这可能会导致样本大小较大。也可能是样本不是特别大,但如果您将message_size_max设置为一个较小的值来强制DDS级分段,则内置DataWriters发送的样本可能会超过此大小并需要分段。
使用异步发送模式可减少DDS碎片
异步发布的优点:
异步发布可能会增加延迟,但具有以下优点:
- write() 调用不进行任何网络调用,因此速度更快、更具确定性。当用户线程正在执行时间关键代码时,这一点变得很重要。
- 当数据以突发方式写入或将大型数据类型作为多个分段发送时,流控制器可以限制异步发布线程的发送速率,以避免淹没网络。
- 针对同一目标的异步写入的 DDS 样本将合并到单个网络数据包中,从而减少带宽消耗。