You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法发送TRDP MD与PD消息:QT集成TRDP库排障求助

TRDP通信发送无数据包排查(QT集成场景)

我正在开发基于TRDP的通信功能,已在QT项目中集成验证过可用的TRDP库。通过初始化Trdp类对象,调用sendPDMessage或sendMDMessage方法发送消息,但接收端未收到任何数据包,Wireshark也捕获不到TRDP数据包,需要协助排查问题。

相关代码

#include "trdp.h"

Trdp::Trdp ( QObject * parent ) : QObject ( parent ) {
    ip[0] = 127;
    ip[1] = 0;
    ip[2] = 0;
    ip[3] = 1;
    comId = PD_COMID;
    this->pubHandle = NULL;

    mdConfiguration = {
        NULL, 
        NULL, 
        {3, 64, 2},
        TRDP_FLAGS_NONE,
        1000000u, 
        1000000u, 
        1000000u, 
        1000000u,  
        17225u, 
        0, 
        5u,
    };

    pdConfiguration = {
        NULL, 
        NULL,
        TRDP_PD_DEFAULT_SEND_PARAM, 
        TRDP_FLAGS_NONE,
        1000000u,
        TRDP_TO_SET_TO_ZERO,
        0u,
    };

    dynamicConfig = { NULL, RESERVED_MEMORY, { 0 } };
    processConfig = {
        "Me", 
        "",
        "",
        TRDP_PROCESS_DEFAULT_CYCLE_TIME, 
        0,
        TRDP_OPTION_NONE
    };
    ownIP = vos_dottedIP("127.0.0.1");
    dstIP = vos_dottedIP("127.0.0.1");
    rv = 0;

    if ( tlc_init ( &this->dbgOut, NULL, &dynamicConfig ) != TRDP_NO_ERR )
    {
        qDebug (  ) << "Init error!"; 
    }

    if ( tlc_openSession ( &appHandle,
                            ownIP,
                            0,
                            NULL,
                            &pdConfiguration,
                            &mdConfiguration,
                            &processConfig ) != TRDP_NO_ERR )
    {
        qDebug (  ) << "Init error! 2";
    }

    memset ( trdpBuffer, 0, sizeof ( trdpBuffer ) );
}

void Trdp::dbgOut (
    void        *pRefCon,
    TRDP_LOG_T  category,
    const CHAR8 *pTime,
    const CHAR8 *pFile,
    UINT16      LineNumber,
    const CHAR8 *pMsgStr)
{  }

// Add this method to initialize a publisher for PD messages
void Trdp::initPDPublisher() {
    TRDP_PUB_T pubHandle = NULL;
    TRDP_ERR_T err = tlp_publish(
        this->appHandle,    // Application session handle
        &pubHandle,         // Publisher handle to be initialized
        NULL,               // User reference
        NULL,               // Callback function for receiving data (not needed for publishing)
        0,                  // Service ID (0 for default) 
        comId,              // Communication ID
        0,                  // etbTopoCnt (0 for default)
        0,                  // etbConfigCnt (0 for default)
        ownIP,              // Source IP address
        dstIP,              // Destination IP address
        1000000u,           // Interval
        0u,                 // Packet time-to-live
        TRDP_FLAGS_NONE,    // Flags
        NULL,               // Marshalling function
        NULL,               // Data pointer (NULL for initialization)
        0                   // Data size (0 for initialization)
    );

    if (err != TRDP_NO_ERR) {
        qDebug() << "Error initializing PD publisher: " << err;
    } else {
        this->pubHandle = pubHandle; // Store the initialized pubHandle for later use
        qDebug() << "PD Publisher initialized successfully.";
    }
}


TRDP_ERR_T Trdp::sendPDMessage(const void *pData, UINT32 dataSize) {
    qDebug() << "Sending PD message" << reinterpret_cast<const UINT8 *>(pData) << "with size" << dataSize;
    const UINT8* data = reinterpret_cast<const UINT8 *>(pData);
    
    // Ensure pubHandle is initialized; call initPDPublisher() before this if not already done
    if (this->pubHandle == NULL) {
        qDebug() << "Publisher not initialized. Initializing now.";
        initPDPublisher();
        if (this->pubHandle == NULL) {
            qDebug() << "Failed to initialize publisher. Cannot send PD message.";
            return TRDP_INIT_ERR;
        }
    }

    TRDP_ERR_T err = tlp_put(
        this->appHandle,    // Use class member appHandle
        this->pubHandle,    // Use the initialized publisher handle
        data,               // Data to send
        dataSize            // Size of the data to send
    );

    if (err != TRDP_NO_ERR) {
        qDebug() << "Error sending PD message: " << err;
    }

    return err;
}

// Method for sending MD messages
TRDP_ERR_T Trdp::sendMDMessage(const void *pData, UINT32 dataSize) {
    qDebug() << "Sending MD message" << reinterpret_cast<const UINT8 *>(pData) << "with size" << dataSize;
    const UINT8* data = reinterpret_cast<const UINT8 *>(pData);

    TRDP_ERR_T err = tlm_request(
        this->appHandle,    // Application session handle
        NULL,               // Message handle (NULL for auto)
        NULL,               // User reference
        NULL,               // Callback function (NULL for no callback)
        1,                  // Service ID (1 for default)
        PD_COMID + 1,                  // ComId (0 for default)
        0,                  // etbTopoCnt (0 for default)
        0,                  // etbConfigCnt (0 for default)
        vos_dottedIP("127.0.0.1"), // Destination IP address
        TRDP_FLAGS_DEFAULT, // Flags
        0,                  // Priority (0 for default)
        1000000u,           // Timeout (in microseconds)
        NULL,               // Marshalling function
        data,               // Data pointer
        dataSize,           // Data size
        NULL,               // Response timeout (NULL for no response)
        NULL                // Response callback (NULL for no callback)
    );

    if (err != TRDP_NO_ERR) {
        qDebug() << "Error sending MD message: " << err;
    } else {
        qDebug() << "MD message sent successfully.";
    }

    return err;
}

排查要点

  • 必须执行TRDP核心循环:TRDP库依赖tlc_processCycle函数处理发送队列、网络IO等核心逻辑,当前代码未调用该函数,导致数据包无法从缓冲区发送到网络。需在QT事件循环中通过QTimer定时调用tlc_processCycle(appHandle),建议调用周期与processConfig中的cycleTime保持一致(默认1ms)。
  • PD消息发送间隔配置:tlp_publish中设置的Interval为1000000u(1秒),tlp_put后TRDP会按此间隔发送数据包。若需立即发送,需将Interval设为0。
  • MD消息参数有效性检查:tlm_request中直接调用vos_dottedIP("127.0.0.1"),需确认返回值有效,建议复用类中已初始化的dstIP变量,避免重复调用可能导致的内存或参数错误。
  • 启用TRDP内部日志:自定义的dbgOut函数为空实现,无法获取库内部的错误信息。需添加日志输出,例如:
    void Trdp::dbgOut (
        void        *pRefCon,
        TRDP_LOG_T  category,
        const CHAR8 *pTime,
        const CHAR8 *pFile,
        UINT16      LineNumber,
        const CHAR8 *pMsgStr)
    {
        qDebug() << "[TRDP Log]" << pTime << pFile << LineNumber << pMsgStr;
    }
    
  • 网络环境验证:确认本地防火墙未拦截UDP端口17225;Wireshark过滤规则需正确,可使用udp.port == 17225或trdp过滤TRDP数据包。
  • Session初始化有效性校验:当前tlc_openSession失败后仍继续执行后续逻辑,需确保appHandle初始化成功后再进行发布和发送操作,避免使用无效句柄。

内容的提问来源于stack exchange,提问作者Evgeni Atanasov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 05:14:51