RTI DDS - CDR缓冲区中没有足够的可用空间

时间:2014-06-18 20:32:57

标签: data-distribution-service

我正在从记录的数据库中播放DDS数据,并编写了一个Java程序来监听数据。我能够很好地接收大部分消息,但是我得到了一些一致的异常,如下所示:

PRESCstReaderCollator_storeSampleData:!deserialize
java.lang.IllegalStateException: not enough available space in CDR buffer
    at com.rti.dds.cdr.CdrBuffer.checkSize(Unknown Source)
    at com.rti.dds.cdr.CdrInputStream.readShortFromBigEndian(Unknown Source)
    at com.rti.dds.cdr.CdrInputStream.deserializeAndSetCdrEncapsulation(Unknown Source)
    at <my type>.deserialize_key_sample(<my type>TypeSupport.java:456)
    at com.rti.dds.topic.TypeSupportImpl.deserialize_key(Unknown Source)
    at com.rti.dds.topic.TypeSupportImpl.deserialize_keyI(Unknown Source)

有没有人看过这个或知道可能导致这种情况的原因?

编辑:我还应该补充一点,我目前正在通过重播数据库使用rtireplay接收DDS数据。在我放弃使用的新重播配置后,我开始收到此错误。所以问题可能是重播配置设置会影响这样的事情?我还要求在IDL中发布混淆的@key字段

struct MyType{
    Key1 key1; //@key
    Key2 key2; //@key
    ...
}

struct Key1 {
    long long m; //@key
    long long l; //@key
    ...
}

//key members only
struct Key2 {
    Key1 a; //@key
    ...
}

1 个答案:

答案 0 :(得分:0)

虽然堆栈跟踪略有不同,但我能够使用以下输出重现类似的情况:

Exception in thread "Thread-5" java.lang.IllegalArgumentException: string length (200)
exceeds maximum (10)
    at com.rti.dds.cdr.CdrInputStream.readString(CdrInputStream.java:364)
    at stringStructTypeSupport.deserialize_key_sample(stringStructTypeSupport.java:411)
    at com.rti.dds.topic.TypeSupportImpl.deserialize_key(TypeSupportImpl.java:1027)
    at com.rti.dds.topic.TypeSupportImpl.deserialize_keyI(TypeSupportImpl.java:965)
PRESCstReaderCollator_storeSampleData:!deserialize

请注意,我使用的是5.1.0,其错误消息更加冗长。

发生这种情况的条件如下:

  • DataReader期望一种类型具有不同的键定义,或者更准确地说,是一种与DataWriter生成的大小不同的键定义。在我的例子中,DataWriter生成了一个200字符的字符串键属性,而DataReader期望一个字符串不超过10个字符。
  • DataWriter的QoS设置protocol.serialize_key_with_dispose设置为true,这意味着在dispose()
  • 如果您使用的是5.1.0或更高版本:发布参与者的QoS设置resource_limits.type_code_max_serialized_lengthresource_limits.type_object_max_serialized_length都设置为0.这样可以避免类型信息的通信,从而防止检测到定义不一致。即使resource_limits设置为非零,旧版本也不会首先检查类型的一致性。
  • 实例为dispose() d
  • 时发生错误

特别是protocol.serialize_key_with_dispose通常不会更改,这似乎是此deserialize_key函数可能出现在堆栈跟踪中的唯一原因。如果您检查rtireplay配置并发现此特定设置已设置为true,那么此处描述的方案极有可能是您的情况。

serialize_key_with_dispose设置允许针对密钥值收到的第一个样本恰好是dispose的情况。这意味着该实例尚不清楚。通常,实际键值不会使用dispose传播,而只会传播散列键。这可能不足以确定dispose用于哪个实例。将此策略设置为true会导致使用dispose传播完整键值。它与propagate_dispose_of_unregistered_instances有关。有关更多详细信息,请参阅{em> 6.5.3.5传播带有处置实例通知的序列化密钥 Connext User's Manual

部分