• qt中用tcp传输xml消息 good


    本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.

     

    环境:

    主机:WIN7

    开发环境:Qt5 3.1.2

    说明:

    在tcp上传输xml消息.

    协议格式如下:

    2字节标识(0xc55c,网络序)+2字节预留 +4字节报文内容长度(网络序) + 4字节命令字(网络序)+报文内容

    部分协议:

    命令字:
    请求值班信息:GET_DUTY_INFO
    请求报文:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <request >  
    3. <identifier>客户端的唯一标识符</identifier>  
    4. </request>  


    回复报文:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <dutyinfo>  
    3.   <version>版本号</version>//表示车辆值班记录有无变化(如增减)  
    4.   <vehiclenum>车辆数目</vehiclenum>  
    5.     <vehicle>  
    6. <dutyofvehicleuid>32位UUID</dutyofvehicleuid>  
    7. <number>车辆编号, 如1,2,3,4</ number>  
    8. <platenumber>车牌号</platenumber>  
    9. <image>图片url</image>  
    10. <liquidlevel>78</liquidlevel>//0至100  
    11.     </vehicle>  
    12.     <vehicle>  
    13. <dutyofvehicleuid>32位UUID</dutyofvehicleuid>  
    14. <number>车辆编号, 如1,2,3,4</ number>  
    15. <platenumber>车牌号</platenumber>  
    16. <image>图片url</image>  
    17. <liquidlevel>78</liquidlevel>//0至100  
    18. </vehicle>  
    19. …  
    20. </dutyinfo>  

    处理思路:

    1.发送:

    调用qt中处理xml文件的类将所需要发送的信息保存为xml文件,然后读取文件,将文件转化为字节流,并拼接帧头,然后发送

    2.接收

    将接收的字节流去掉帧头后保存为xml文件,然后调用qt中处理xml文件的类读取其中的信息

    源代码:

    保存为xml文件

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. //打开需要发送的xml命令  
    2.     QFile file(FILE_GET_DUTY_TX);  
    3.     //生成xml文件  
    4.     QDomDocument doc;  
    5.     QDomElement root_elem;  
    6.     QDomElement item;  
    7.     QDomText text;  
    8.   
    9.     //xml文件头  
    10.     QString header("version="1.0" encoding="UTF-8"");  
    11.     doc.appendChild(doc.createProcessingInstruction("xml",header));  
    12.   
    13.     //根元素  
    14.     root_elem = doc.createElement("request");  
    15.     doc.appendChild(root_elem);  
    16.   
    17.     //元素:identifier  
    18.     item = doc.createElement("identifier");  
    19.     text = doc.createTextNode(QString(Local_Id));  
    20.     item.appendChild(text);  
    21.     root_elem.appendChild(item);  
    22.   
    23.     //新建文件并保存  
    24.     file.open(QIODevice::WriteOnly);  
    25.     QTextStream out(&file);  
    26.     out.setCodec("UTF-8");  
    27.     doc.save(out,4,QDomNode::EncodingFromTextStream);  
    28.     file.close();  


    读取xml文件,得到字节流

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. //读取xml文件  
    2.     file.open(QIODevice::ReadOnly);  
    3.     QTextStream get(&file);  
    4.     //得到xml数据  
    5.     Data_Xml_Tx = get.readAll().toLocal8Bit();  
    6.     file.close();  


    发送函数

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. /********************************************************************* 
    2. *                               槽函数:发送网络帧 
    3. *参数:cmd:帧命令 
    4. *    frame:发送的报文 
    5. **********************************************************************/  
    6.   
    7. void Net::slot_net_tx_frame(int cmd,QByteArray frame)  
    8. {  
    9.     QByteArray head;  
    10.     int i = 0;  
    11.   
    12.     i = 0;  
    13.     //帧头  
    14.     head[i++] = 0xc5;  
    15.     head[i++] = 0x5c;  
    16.     //预留  
    17.     head[i++] = 0;  
    18.     head[i++] = 0;  
    19.     //报文长度  
    20.     head[i++] = frame.size() >> 24;  
    21.     head[i++] = frame.size() >> 16;  
    22.     head[i++] = frame.size() >> 8;  
    23.     head[i++] = frame.size();  
    24.     //命令字  
    25.     head[i++] = cmd >> 24;  
    26.     head[i++] = cmd >> 16;  
    27.     head[i++] = cmd >> 8;  
    28.     head[i++] = cmd;  
    29.     //组合帧  
    30.     frame.prepend(head);  
    31.   
    32.     //判断当前是否连接上服务器  
    33.     if (tcp_client->state() == QAbstractSocket::ConnectedState)  
    34.     {  
    35.         //已连接上  
    36.         //发送数据  
    37.         tcp_client->write(frame);  
    38.   
    39.     #ifdef DEBUG  
    40.         qDebug() << "发送网络帧1:cmd" << cmd;  
    41.     #endif  
    42.     }  
    43.     else  
    44.     {  
    45.         //未连接上  
    46.         Frame = frame;  
    47.         //连接服务器  
    48.         if (tcp_client->state() != QAbstractSocket::ConnectingState)  
    49.         {  
    50.             tcp_client->connectToHost(Server_Ip,Server_Port);  
    51.         }  
    52.     }  
    53. }  


    tcp接收网络帧,并保存为xml文件,然后读取xml文件中的信息

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. /********************************************************************* 
    2. *                               接收完成处理 
    3. **********************************************************************/  
    4.   
    5. void Get_Duty::deal_frame()  
    6. {  
    7.     int sum = 0;  
    8.     int i = 0;  
    9.     QSqlQuery q;  
    10.     QString version;  
    11.   
    12.     //解锁  
    13.     Lock_Net = 0;  
    14.     //放弃处理网络信息  
    15.     Net_Permission = 0;  
    16.   
    17.     qDebug() << "接收帧:回复值班信息";  
    18.   
    19.     //判断是否有值班信息  
    20.     if ((uint8_t)Frame.at(11) == 0)  
    21.     {  
    22.         //有标题,将数据存入xml文件  
    23.         //打开接收命令存储的xml文件  
    24.         QFile file(FILE_GET_DUTY_RX);  
    25.         //新建文件并保存  
    26.         file.open(QIODevice::WriteOnly);  
    27.         QTextStream out(&file);  
    28.         out.setCodec("UTF-8");  
    29.         out << Frame.mid(LEN_FRAME_HEAD);  
    30.         file.close();  
    31.   
    32.         //打开xml文件  
    33.         QDomDocument doc(FILE_GET_DUTY_RX);  
    34.         //获取文件内容  
    35.         file.open(QIODevice::ReadOnly);  
    36.         doc.setContent(&file);  
    37.         file.close();  
    38.   
    39.         //获得根节点  
    40.         QDomElement root_node = doc.documentElement();  
    41.         //获得第一个子节点:版本  
    42.         QDomNode node = root_node.firstChild();  
    43.         version = node.toElement().text();  
    44.         //判断版本号是否一致  
    45.         if (version == Version)  
    46.         {  
    47.             return;  
    48.         }  
    49.   
    50.         //不一致  
    51.         Version = version;  
    52.         qDebug() << "版本号" << Version;  
    53.   
    54.         //下一个子节点:车辆总数  
    55.         node = node.nextSibling();  
    56.         sum = node.toElement().text().toInt();  
    57.         qDebug() << "车辆总数" << sum;  
    58.   
    59.         //清空前3辆车辆信息  
    60.         Car_Three_List[0].clear();  
    61.         Car_Three_List[1].clear();  
    62.         Car_Three_List[2].clear();  
    63.         //清空值班信息表  
    64.         q.prepare("DELETE FROM duty");  
    65.         q.exec();  
    66.         //写入数据库  
    67.         for (i = 0;i < sum;i++)  
    68.         {  
    69.             node = node.nextSibling();  
    70.   
    71.             //插入数据  
    72.             q.prepare("INSERT INTO duty VALUES(?,?,?,?,?,?)");  
    73.             //uuid  
    74.             q.bindValue(0,node.toElement().childNodes().at(0).toElement().text());  
    75.             //编号  
    76.             q.bindValue(1,node.toElement().childNodes().at(1).toElement().text().toInt());  
    77.             //车牌  
    78.             q.bindValue(2,node.toElement().childNodes().at(2).toElement().text());  
    79.             //图片  
    80.             q.bindValue(3,node.toElement().childNodes().at(3).toElement().text());  
    81.             //汽油  
    82.             q.bindValue(4,node.toElement().childNodes().at(4).toElement().text().toInt());  
    83.             //图片标志  
    84.             q.bindValue(5,IMG_NULL);  
    85.             q.exec();  
    86.   
    87.             //前3辆车辆信息输入  
    88.             if (i < 3)  
    89.             {  
    90.                 Car_Three_List[i] = node.toElement().childNodes().at(0).toElement().text();  
    91.             }  
    92.         }  
    93.   
    94.         //打印数据库  
    95. //        q.prepare("SELECT * FROM duty");  
    96. //        q.exec();  
    97. //        while (q.next())  
    98. //        {  
    99. //            qDebug() << "uuid" << q.value(0).toString()  
    100. //                     << "编号" << q.value(1).toInt()  
    101. //                     << "车牌" << q.value(2).toString()  
    102. //                     << "图片" << q.value(3).toString()  
    103. //                     << "汽油" << q.value(4).toString()  
    104. //                     << "图片标志" << q.value(5).toInt();  
    105. //        }  
    106.     }  
    107.     else  
    108.     {  
    109.         Version = "null";  
    110.   
    111.         //清空值班信息表  
    112.         q.prepare("DELETE FROM duty");  
    113.         q.exec();  
    114.     }  
    115.   
    116.     //接收到值班信息  
    117.     emit sig_recv_duty_info();  
    118.   
    119.     //清空接收缓存  
    120.     Frame.clear();  
    121.     Len_Frame_Content = 0;  

    http://blog.csdn.net/jdh99/article/details/38677811

  • 相关阅读:
    mysql json 字符串
    《滕王阁序》
    Jmeter(四十八)MQ测试(转!)
    Echarts 实线与虚线一起使用
    Oracle表空间自动扩展设置
    sql注入条件判断bypass系列
    Jmeter分布式压力测试(史上最全)
    Nginx生产环境配置、elasticsearch生产环境配置、rocketmq生产环境配置 (史上最全)
    Websocket协议 详解(rfc6455)
    Flux 和 Mono 、reactor实战 (史上最全)
  • 原文地址:https://www.cnblogs.com/findumars/p/6152880.html
Copyright © 2020-2023  润新知