在qt中用tcp传输xml消息

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


环境:

主机:WIN7

开发环境:Qt5 3.1.2

说明:

在tcp上传输xml消息.

协议格式例如以下:

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

部分协议:

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

<?xml version="1.0" encoding="UTF-8"?>
<request >
<identifier>客户端的唯一标识符</identifier>
</request>

回复报文:

<?xml version="1.0" encoding="UTF-8"?>
<dutyinfo>
<version>版本号号</version>//表示车辆值班记录有无变化(如增减)
<vehiclenum>车辆数目</vehiclenum>
<vehicle>
<dutyofvehicleuid>32位UUID</dutyofvehicleuid>
<number>车辆编号, 如1,2,3,4</ number>
<platenumber>车牌号</platenumber>
<image>图片url</image>
<liquidlevel>78</liquidlevel>//0至100
</vehicle>
<vehicle>
<dutyofvehicleuid>32位UUID</dutyofvehicleuid>
<number>车辆编号, 如1,2,3,4</ number>
<platenumber>车牌号</platenumber>
<image>图片url</image>
<liquidlevel>78</liquidlevel>//0至100
</vehicle>

</dutyinfo>

处理思路:

1.发送:

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

2.接收

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

源码:

保存为xml文件

//打开须要发送的xml命令
QFile file(FILE_GET_DUTY_TX);
//生成xml文件
QDomDocument doc;
QDomElement root_elem;
QDomElement item;
QDomText text; //xml文件头
QString header("version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(doc.createProcessingInstruction("xml",header)); //根元素
root_elem = doc.createElement("request");
doc.appendChild(root_elem); //元素:identifier
item = doc.createElement("identifier");
text = doc.createTextNode(QString(Local_Id));
item.appendChild(text);
root_elem.appendChild(item); //新建文件并保存
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
out.setCodec("UTF-8");
doc.save(out,4,QDomNode::EncodingFromTextStream);
file.close();

读取xml文件,得到字节流

//读取xml文件
file.open(QIODevice::ReadOnly);
QTextStream get(&file);
//得到xml数据
Data_Xml_Tx = get.readAll().toLocal8Bit();
file.close();

发送函数

/*********************************************************************
* 槽函数:发送网络帧
*參数:cmd:帧命令
* frame:发送的报文
**********************************************************************/ void Net::slot_net_tx_frame(int cmd,QByteArray frame)
{
QByteArray head;
int i = 0; i = 0;
//帧头
head[i++] = 0xc5;
head[i++] = 0x5c;
//预留
head[i++] = 0;
head[i++] = 0;
//报文长度
head[i++] = frame.size() >> 24;
head[i++] = frame.size() >> 16;
head[i++] = frame.size() >> 8;
head[i++] = frame.size();
//命令字
head[i++] = cmd >> 24;
head[i++] = cmd >> 16;
head[i++] = cmd >> 8;
head[i++] = cmd;
//组合帧
frame.prepend(head); //推断当前是否连接上server
if (tcp_client->state() == QAbstractSocket::ConnectedState)
{
//已连接上
//发送数据
tcp_client->write(frame); #ifdef DEBUG
qDebug() << "发送网络帧1:cmd" << cmd;
#endif
}
else
{
//未连接上
Frame = frame;
//连接server
if (tcp_client->state() != QAbstractSocket::ConnectingState)
{
tcp_client->connectToHost(Server_Ip,Server_Port);
}
}
}

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

/*********************************************************************
* 接收完毕处理
**********************************************************************/ void Get_Duty::deal_frame()
{
int sum = 0;
int i = 0;
QSqlQuery q;
QString version; //解锁
Lock_Net = 0;
//放弃处理网络信息
Net_Permission = 0; qDebug() << "接收帧:回复值班信息"; //推断是否有值班信息
if ((uint8_t)Frame.at(11) == 0)
{
//有标题,将数据存入xml文件
//打开接收命令存储的xml文件
QFile file(FILE_GET_DUTY_RX);
//新建文件并保存
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
out.setCodec("UTF-8");
out << Frame.mid(LEN_FRAME_HEAD);
file.close(); //打开xml文件
QDomDocument doc(FILE_GET_DUTY_RX);
//获取文件内容
file.open(QIODevice::ReadOnly);
doc.setContent(&file);
file.close(); //获得根节点
QDomElement root_node = doc.documentElement();
//获得第一个子节点:版本号
QDomNode node = root_node.firstChild();
version = node.toElement().text();
//推断版本号号是否一致
if (version == Version)
{
return;
} //不一致
Version = version;
qDebug() << "版本号号" << Version; //下一个子节点:车辆总数
node = node.nextSibling();
sum = node.toElement().text().toInt();
qDebug() << "车辆总数" << sum; //清空前3辆车辆信息
Car_Three_List[0].clear();
Car_Three_List[1].clear();
Car_Three_List[2].clear();
//清空值班信息表
q.prepare("DELETE FROM duty");
q.exec();
//写入数据库
for (i = 0;i < sum;i++)
{
node = node.nextSibling(); //插入数据
q.prepare("INSERT INTO duty VALUES(?,?,?,?,?,?)");
//uuid
q.bindValue(0,node.toElement().childNodes().at(0).toElement().text());
//编号
q.bindValue(1,node.toElement().childNodes().at(1).toElement().text().toInt());
//车牌
q.bindValue(2,node.toElement().childNodes().at(2).toElement().text());
//图片
q.bindValue(3,node.toElement().childNodes().at(3).toElement().text());
//汽油
q.bindValue(4,node.toElement().childNodes().at(4).toElement().text().toInt());
//图片标志
q.bindValue(5,IMG_NULL);
q.exec(); //前3辆车辆信息输入
if (i < 3)
{
Car_Three_List[i] = node.toElement().childNodes().at(0).toElement().text();
}
} //打印数据库
// q.prepare("SELECT * FROM duty");
// q.exec();
// while (q.next())
// {
// qDebug() << "uuid" << q.value(0).toString()
// << "编号" << q.value(1).toInt()
// << "车牌" << q.value(2).toString()
// << "图片" << q.value(3).toString()
// << "汽油" << q.value(4).toString()
// << "图片标志" << q.value(5).toInt();
// }
}
else
{
Version = "null"; //清空值班信息表
q.prepare("DELETE FROM duty");
q.exec();
} //接收到值班信息
emit sig_recv_duty_info(); //清空接收缓存
Frame.clear();
Len_Frame_Content = 0;
}

在qt中用tcp传输xml消息的更多相关文章

  1. qt中用tcp传输xml消息 good

    本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.   环境: 主机:WIN7 开发环境:Qt5 3.1.2 说明: 在tcp上传输xml消息. 协议格式如 ...

  2. Qt5 基于TCP传输的发送/接收文件服务器(支持多客户端)

    一.实现功能 1.服务器端选择待发送的文件,可以是多个 2.开启服务器,支持多客户端接入,能够实时显示每个客户端接入状态 3.等待所有客户端都处于已连接状态时,依次发送文件集给每个客户端,显示每个客户 ...

  3. Qt实现客户端与服务器消息发送与文件传输

    Qt实现客户端与服务器消息发送与文件传输需要使用到 QTcpSocket:提供套接字QTcpServer:提供基于TCP的服务端,官方文档的解释如下: This class makes it poss ...

  4. Qt实现客户端与服务器消息发送

    这里用Qt来简单设计实现一个场景,即: ①两端:服务器QtServer和客户端QtClient ②功能:服务端连接客户端,两者能够互相发送消息,传送文件,并且显示文件传送进度. 环境:VS20013+ ...

  5. 基于Qt的Tcp协议的流程图

    TCP(Transmission Control Protocol传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.在qt中,Tcp协议主要是用QTcpServer和QTcpSock ...

  6. QT实现TCP通信服务器端和客户端(支持多个客户端)精简版

    上星期接了个私活,工期两星期,报酬3000,写一个小软件,采集定向网络上的数据,并进行双向通信,捣鼓了两天,终于把QT中tcp通信这块调通了,找过N多例子,绝大部分都是基本的一个服务端一个客户端通信的 ...

  7. Android设备一对多录屏直播--(UDP组播连接,Tcp传输)

    原文:https://blog.csdn.net/sunmmer123/article/details/82734245 近期需要学习流媒体知识,做一个Android设备相互投屏Demo,因此找到了这 ...

  8. 转:TCP为什么要3次握手和4次挥手时等待2MSL、 TCP如何保证消息顺序以及可靠性到达

    关于tcp三次握手.四次挥手可以看这里:TCP与UDP的差别以及TCP三次握手.四次挥手 1.TCP为甚要3次握手? 在谢希仁著<计算机网络>第四版中讲“三次握手”的目的是“为了防止已失效 ...

  9. Java开发笔记(一百一十四)利用Socket传输文本消息

    前面介绍了HTTP协议的网络通信,包括接口调用.文件下载和文件上传,这些功能固然已经覆盖了常见的联网操作,可是HTTP协议拥有专门的通信规则,这些规则一方面有利于维持正常的数据交互,另一方面不可避免地 ...

随机推荐

  1. javascript 剔除数组中相同的值,合并数组中相同项

    var a = ["2013-01","2013-01","2013-02","2013-02","2013- ...

  2. Codeforces Round #112 (Div. 2)---A. Supercentral Point

    Supercentral Point time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  3. timesetevent与timekillevent的用法

    unit Unit1; interface uses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs ...

  4. JavaScript进阶(三) 值传递和引用传递

    从C语言开始 有时候讲一些细节或是底层的东西,我喜欢用C语言来讲,因为用C更方便来描述内存里面的东西.先举一个例子,swap函数,相信有一些编程经验的人都见识过,声明如下,函数体我就不写了,各位脑补一 ...

  5. jQuery中对 input 控件的操作

    jquery radio取值,checkbox取值,select取值,radio选中,checkbox选中,select选中,及其相关 1.获取值 jquery取radio单选按钮的值 $(" ...

  6. Servlet的学习之Response响应对象(2)

    本篇接上一篇<Servlet的学习之Response响应对象(1)>,继续从HttpServletResponse响应对象来介绍其方法和功能. 使用setHeader方法结合HTTP协议的 ...

  7. 如何让DbGrid支持鼠标滚轮滚动

    如何让DbGrid支持鼠标滚轮滚动 在主窗体上加一个ApplicationEvents控件(控件在Additional面板中), 在它的OnMessage事件中加入下述代码,一切搞定-! proced ...

  8. C++运算符重载的方法

    运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算.也就是说,运算符重载是通过定义函数实现的. 运算符重载实质上是函数的重载 重载运算符的函 ...

  9. ExtJs4 笔记(13) Ext.menu.Menu 菜单、Ext.draw.Component 绘图、Ext.resizer.Resizer 大小变更

    本篇讲解菜单.绘图.还有大小变更控件.菜单控件可以附加到各种其他控件中,比如按钮.工具栏等,甚至可以直接通过通过右键打开(模拟右键菜单):ext对绘图的支持可以让我们通过js来绘图:大小变更控件可以让 ...

  10. qt槽函数中,窗口镶嵌窗口的问题,求解

    my_label=newQLabel(ui->widget); my_Label->setText("yvhvv"); 我把这插入到构造函数中,正确显示. 我把这插入到 ...