基于QTcpSocket和QTcpServer的Tcp通讯以及QDataStream序列化数据
为什么80%的码农都做不了架构师?>>>
最近要在QT下开发Tcp通讯,发送序列化数据以便于接收。
这里涉及到几个问题:
1.QTcpSocket、QTcpServer的通讯
2.QDataStream序列化数据
多的不说,直接上干货!!!
客户端:
tcpclient.h
1 #ifndef TCPCLIENT_H
2 #define TCPCLIENT_H
3
4 #include <QMainWindow>
5 #include <qt4/Qt/qtcpsocket.h>
6 #include <Qt/qhostinfo.h>
7 #include <QDataStream>
8 #include <QtNetwork>
9
10
11
12 struct Control_Motor
13 {
14 int length;
15 int command;
16 QString data;
17 };
18
19
20 class Motor
21 {
22 public:
23 Motor(){}
24 Motor(int speed,int accele_speed,int p_some)
25 {
26 m_speed = speed;
27 m_accele_speed = accele_speed;
28 m_p_some = p_some;
29 }
30
31
32
33 public:
34 int getV(){return m_speed;}
35 int getA(){return m_accele_speed;}
36 int getP(){return m_p_some;}
37
38 void setV(const int v){m_speed = v;}
39 void setA(const int a){m_accele_speed = a;}
40 void setP(const int p){m_p_some = p;}
41
42
43
44 public:
45 //friend QDataStream & operator <<(QDataStream &out,const Motor &motor);
46 //friend QDataStream & operator >>(QDataStream &in,Motor &motor);
47 /*
48 friend QDataStream & operator <<(QDataStream &out,Motor &motor)
49 {
50 out << motor.m_speed<<motor.m_p_some<<motor.m_accele_speed;
51 qDebug()<< motor.m_speed<<motor.m_p_some<<motor.m_accele_speed<<"Enter in this";
52 return out;
53 }
54 */
55 public:
56 int m_speed;
57 int m_accele_speed;
58 int m_p_some;
59
60 };
61
62
63 namespace Ui {
64 class TcpClient;
65 }
66
67 class TcpClient : public QMainWindow
68 {
69 Q_OBJECT
70
71 public:
72 explicit TcpClient(QWidget *parent = 0);
73 ~TcpClient();
74
75 private:
76 Ui::TcpClient *ui;
77 QTcpSocket *tcpClient;
78
79
80 private slots:
81 void slotConnect();
82 void readMessage();
83 void displayError(QAbstractSocket::SocketError);
84 void sendMessage();
85
86
87
88 public:
89 Control_Motor control_Motor;
90
91 Motor *m_motor;
92
93 };
94
95
96 #endif // TCPCLIENT_H
tcpclient.cpp
1 #include "tcpclient.h"
2 #include "ui_tcpclient.h"
3 #include <QFile>
4 #include <QDataStream>
5
6
7 QDataStream & operator<<(QDataStream &out,const Motor &motor)
8 {
9 //qDebug()<< motor.m_speed<<motor.m_p_some<<motor.m_accele_speed<<"Enter in";
10 out << motor.m_speed<<motor.m_p_some<<motor.m_accele_speed;
11 //qDebug()<< motor.m_speed<<motor.m_p_some<<motor.m_accele_speed<<"Enter in this";
12 return out;
13 }
14
15 QDataStream &operator >>(QDataStream &in,Motor &motor)
16 {
17 int speed = 0;
18 int accele_speed =0;
19 int p_some = 0;
20
21 in >> speed >> p_some >> accele_speed;
22
23 motor.setV(speed);
24 motor.setP(p_some);
25 motor.setA(accele_speed);
26
27 return in;
28 }
29 Q_DECLARE_METATYPE(Motor)
30
31
32 TcpClient::TcpClient(QWidget *parent) :
33 QMainWindow(parent),
34 ui(new Ui::TcpClient)
35 {
36 ui->setupUi(this);
37
38 qRegisterMetaType<Motor>("Motor");
39
40 tcpClient = new QTcpSocket(this);
41 connect(ui->Connect_Btn,SIGNAL(clicked()),this,SLOT(slotConnect()));
42 connect(ui->Send_Btn,SIGNAL(clicked()),this,SLOT(sendMessage()));
43 connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readMessage()));
44 connect(tcpClient, SIGNAL(error(QAbstractSocket::SocketError)), this,
45 SLOT(displayError(QAbstractSocket::SocketError)));
46 }
47
48 TcpClient::~TcpClient()
49 {
50 delete ui;
51 }
52
53 void TcpClient::slotConnect()
54 {
55 //QString stringAddress = ui->ldt_IP->text();
56 //QString stringPort = ui->ldt_Port->text();
57 QString stringAddress = "192.168.154.128";
58 QString stringPort = "8080";
59 int port = stringPort.toInt();
60 QHostAddress address;
61 address.setAddress(stringAddress);
62 tcpClient->abort();
63 tcpClient->connectToHost(address,port);
64 ui->Connect_Btn->setEnabled(false);
65 }
66
67 void TcpClient::readMessage()
68 {
69
70 }
71
72 void TcpClient::displayError(QAbstractSocket::SocketError)
73 {
74 qDebug() << tcpClient->errorString();
75 }
76
77 void TcpClient::sendMessage()
78 {
79 QString stringMotor = ui->ldt_Motor->text();
80 QString stringData = ui->ldt_data->text();
81 control_Motor.command = stringMotor.toInt();
82 int dataLength = stringData.length();
83 control_Motor.length = 8 + dataLength;
84 control_Motor.data = stringData;
85 QString data = stringMotor+stringData;
86
87 m_motor = new Motor(20,40,60);
88
89 //Motor m_motor(20,40,60);
90
91 //用于暂存要发送的数据
92 QByteArray block;
93 //使用数据流写入数据
94 QDataStream out(&block,QIODevice::WriteOnly);
95 //设置数据流的版本,客户端和服务器端使用的版本要相同
96 out.setVersion(QDataStream::Qt_4_6);
97 out<<(quint32) 0;
98 //设置发送长度初始值为0
99 //out << control_Motor.length<<control_Motor.command<<control_Motor.data;
100
101 //qDebug() << control_Motor.length<<control_Motor.command<<control_Motor.data;
102 //out
103 out << control_Motor.command;
104 qDebug()<<"Start out"<<endl;
105 out << *m_motor;
106 qDebug()<<"End out"<<endl;
107 qDebug() << control_Motor.command<< m_motor->getA()<<m_motor->getP()<<m_motor->getV();
108 //回到字节流起始位置
109 out.device()->seek(0);
110 //重置字节流长度
111 //out << (quint16) (block.size()-sizeof(quint16));
112 out << (quint32)(block.size()- sizeof(quint32));
113 qDebug() << "block.size()"<<block.size();
114
115 //往套接字缓存中写入数据,并发送
116 tcpClient->write(block,block.size());
117 tcpClient->disconnectFromHost();
118 tcpClient->waitForDisconnected();
119
120 block.resize(0);
121 this->close();
122 //tcpClient->write(data.toLatin1(),data.size());
123 }
服务器端:
tcpserver.h
1 ifndef TCPSERVER_H
2 #define TCPSERVER_H
3
4 #include <QMainWindow>
5 #include <qt4/Qt/qhostinfo.h>
6 #include "server.h"
7
8
9 namespace Ui {
10 class TcpServer;
11 }
12
13 class TcpServer : public QMainWindow
14 {
15 Q_OBJECT
16
17 public:
18 explicit TcpServer(QWidget *parent = 0);
19 ~TcpServer();
20
21 private:
22 Ui::TcpServer *ui;
23 int port;
24 Server *server;
25
26 protected slots:
27 void slotCreateServer();
28 void updateServer(QString,int);
29
30 };
31
32 #endif // TCPSERVER_H
tcpserver.cpp
1 #include "tcpserver.h"
2 #include "ui_tcpserver.h"
3 #include <QtNetwork/QNetworkInterface>
4
5 TcpServer::TcpServer(QWidget *parent) :
6 QMainWindow(parent),
7 ui(new Ui::TcpServer)
8 {
9 ui->setupUi(this);
10 port = 8080;
11 QString address = QNetworkInterface::allAddresses().first().toString();
12 QList<QHostAddress> list2 = QNetworkInterface::allAddresses();
13 foreach (QHostAddress address, list2)
14 {
15 if(address.protocol() == QAbstractSocket::IPv4Protocol)
16 ui->ldt_IP->setText(address.toString());
17 }
18 ui->ldt_Port->setText(QString::number(port));
19 connect(ui->Connect_Btn,SIGNAL(clicked()),this,SLOT(slotCreateServer()));
20 }
21
22 TcpServer::~TcpServer()
23 {
24 delete ui;
25 }
26
27 void TcpServer::slotCreateServer()
28 {
29 server = new Server(this,port);
30 connect(server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));
31 ui->Connect_Btn->setEnabled(false);
32 }
33
34 void TcpServer::updateServer(QString msg, int length)
35 {
36 ui->lwt_Text->addItem(msg.left(length));
37 }
server.h
1 #ifndef SERVER_H
2 #define SERVER_H
3
4 #include <qt4/Qt/qtcpserver.h>
5 #include <qt4/Qt/qtcpsocket.h>
6
7 struct Control_Motor
8 {
9 int length;
10 int command;
11 QString data;
12 };
13
14
15 class Motor
16 {
17 public:
18 Motor(int speed,int accele_speed,int p_some)
19 {
20 m_speed = speed;
21 m_accele_speed = accele_speed;
22 m_p_some = p_some;
23 }
24
25 Motor(){m_speed = 0;}
26
27
28
29 public:
30 int getV(){return m_speed;}
31 int getA(){return m_accele_speed;}
32 int getP(){return m_p_some;}
33
34 void setV(const int v){m_speed = v;}
35 void setA(const int a){m_accele_speed = a;}
36 void setP(const int p){m_p_some = p;}
37
38
39
40 private:
41 int m_speed;
42 int m_accele_speed;
43 int m_p_some;
44
45 };
46
47
48
49 class Server : public QTcpServer
50 {
51 Q_OBJECT
52
53 public:
54 Server(QObject *parents=0,int port=0);
55 QList<QTcpSocket*>TcpClientSocketList;
56 QTcpSocket *tcpClientSocket;
57 signals:
58 void updateServer(QString,int);
59
60 public slots:
61 void slotUpdateClient(QString,int);
62 void slotDisconnect(int);
63 // void slotnewconnection();
64 protected:
65 void incomingConnection(int socketDescriptor);
66
67 signals:
68 void updateClients(QString,int);
69 void disconnected(int);
70
71 protected slots:
72 void dataReceive();
73 void slotDisconnected();
74
75 public:
76 Control_Motor control_motor;
77 Motor m_mtor;
78 };
79
80 #endif // SERVER_H
server.cpp
1 #include "server.h"
2
3 QDataStream &operator <<(QDataStream &out,Motor &motor)
4 {
5 out << motor.getV()<<motor.getP()<<motor.getA();
6 return out;
7 }
8
9
10 QDataStream &operator >>(QDataStream &in,Motor &motor)
11 {
12 int speed = motor.getV();
13 int accele_speed =motor.getA();
14 int p_some = motor.getP();
15
16 in >> speed >> p_some >> accele_speed;
17
18 motor.setV(speed);
19 motor.setP(p_some);
20 motor.setA(accele_speed);
21
22 return in;
23 }
24
25
26
27
28 Server::Server(QObject *parent,int port) :
29 QTcpServer(parent)
30 {
31 this->listen(QHostAddress::Any,port);
32 }
33
34 void Server::incomingConnection(int socketDescriptor)
35 {
36 tcpClientSocket = new QTcpSocket(this);
37 //tcpClientSocket = this->nextPendingConnection();
38 tcpClientSocket->setSocketDescriptor(socketDescriptor);
39 TcpClientSocketList.append(tcpClientSocket);
40 //connect(this,SIGNAL(updateClients(QString,int)),this,SLOT(slotUpdateClient(QString,int)));
41 //connect(this,SIGNAL(updateClients(QString,int)),this,SLOT(slotUpdateClient(QString,int)));
42 connect(this,SIGNAL(disconnected(int)),this,SLOT(slotDisconnect(int)));
43 connect(tcpClientSocket,SIGNAL(readyRead()),this,SLOT(dataReceive()));
44 connect(tcpClientSocket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
45 //connect(tcpClientSocket,SIGNAL(disconnected()),tcpClientSocket,SLOT(deleteLater()));
46
47 }
48 void Server::slotUpdateClient(QString msg,int length)
49 {
50 emit updateServer(msg,length);
51 for (int i=0;i<TcpClientSocketList.count();i++)
52 {
53 QTcpSocket *item=TcpClientSocketList.at(i);
54 if (item->write(msg.toLatin1(),length)!=length)
55 continue;
56 }
57 }
58 void Server::slotDisconnect(int socketDescriptor)
59 {
60 qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<<endl;
61 for (int i=0;i<TcpClientSocketList.count();i++)
62 if (TcpClientSocketList.at(i)->socketDescriptor()==socketDescriptor)
63 {
64 TcpClientSocketList.removeAt(i);
65 return;
66 }
67 }
68
69 void Server::dataReceive()
70 {
71 qDebug()<<"QQWQW11111111111111";
72 //quint32 size = 0;
73 quint32 nextBlockSize = 0;
74 qDebug()<<"TcpClientSocketList.count()"<<TcpClientSocketList.count();
75 //for(int i = 0; i < TcpClientSocketList.count();i++)
76 //{
77 QDataStream in(tcpClientSocket);
78 in.setVersion(QDataStream::Qt_4_6);
79 if(nextBlockSize == 0)
80 {
81 if(tcpClientSocket->bytesAvailable()<sizeof(quint32))
82 {
83 //break;
84 return;
85 }
86 in>>nextBlockSize;
87 qDebug()<<nextBlockSize;
88 }
89 if(nextBlockSize==0xFFFF)
90 {
91 //break;
92 return;
93 }
94 if(tcpClientSocket->bytesAvailable()<nextBlockSize)
95 {
96 //break;
97 return;
98 }
99
100 //in>>control_motor.length>>control_motor.command>>control_motor.data;
101
102 //qDebug()<<control_motor.length<<control_motor.command<<control_motor.data;
103 in >>control_motor.command >> m_mtor;
104 qDebug()<<control_motor.command<< m_mtor.getA()<<m_mtor.getP()<<m_mtor.getV();
105
106 //ui->SN_lineEdit_2->setText(QString("%1").arg(message_rev.SN));
107 //ui->IP_lineEdit->setText(message_rev.IP);
108 //ui->STATE_lineEdit_3->setText(message_rev.Condition);
109 //}
110 }
111
112 void Server::slotDisconnected()
113 {
114 qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<<endl;
115 emit disconnected(tcpClientSocket->socketDescriptor());
116 }
在这里要特别说明一下,在此遇到的几个问题,希望能帮到大家,也提醒一下自己。
1.在TcpClient.pro,TcpServer.pro里一定要注意加上QT += network,不然编译的时候QNetworkInterface、QHostAddress这些地方会报错误。
2.在QDataStream重载自定义的类的时候,一开始把重载写在.h文件里编译的时候总是报Tcp_DataStream/TcpServer/server.h:49: error: multiple definition of `operator<<(QDataStream&, Motor&)'这个错误,说实话这个问题真的困扰了我很久,然后把重载函数放到.cpp文件里,编译通过,简直是要命
3.QDataStream的nextBlock读取到的长度为发送的数据的长度(而不是整个包的长度out << (quint32)(block.size()- sizeof(quint32));),如果直接写out << (quint32)(block.size()),读的时候数据将会不正常。
4.重载的时候一定要正确。
源代码连接:http://download.csdn.net/detail/cmp15845953187/8800409
转载于:https://my.oschina.net/qtplus/blog/1942299
基于QTcpSocket和QTcpServer的Tcp通讯以及QDataStream序列化数据相关推荐
- 基于STM32和W5500的Modbus TCP通讯
在最近的一个项目中需要实现Modbus TCP通讯,而选用的硬件平台则是STM32F103和W5500,软件平台则选用IAR EWAR6.4来实现. 1.移植前的准备工作 为了实现Modbus ...
- 《 Python程序设计项目案例》— 用Python开发的基于TCP通讯协议的私人聊天室 (期末大作业、结课作业、课程设计、毕业设计)
基于Python与TCP协议的私人聊天室(GUI交互界面,用户注册.用户登录.实时聊天,文件上传与下载) 用Python开发的基于TCP通讯协议的实时聊天通讯和文件共享应用 目录 基于Python与T ...
- 基于MDKA5D31-EK_T70开发板的QT示例-demo08:TCP通讯
By Mcuzone 硬件平台:MDKA5D31-EK_T70开发板 QT版本:4.8.5 简要说明:本示例主要演示应用程序作为UDP服务器和客户端的通讯过程. 应用程序运行效果: 一.网络连接: ...
- 基于Golang TCP 开发网络游戏 CLI四川麻将 - 2.Tcp通讯
项目地址 https://github.com/mangenotwork/CLI-Sichuan-Mahjong 数据传输结构定义 这里使用gob序列化数据 // entity.gotype Tran ...
- Beetle在Tcp通讯中使用Protobuf
Protobuf是google制定的一种对象序列化格式,而在.net下的实现有protobuf-net.而protobuf-net在序列化方面有着出色的性能,效率是.net二进制序列化几倍,而序列化后 ...
- JAVA通信编程(三)——TCP通讯
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
- tcp通讯一次最多能发送多少数据?_关于TCP/IP,必须知道的十个知识点
本文整理了一些TCP/IP协议簇中需要必知必会的十大问题,既是面试高频问题,又是程序员必备基础素养. 一.TCP/IP模型 TCP/IP协议模型(Transmission Control Protoc ...
- Silverlight使用RSA加密socket tcp通讯数据
在tcp通讯中为了数据安全在某些情况下对数据进行加密传输是很有必要的,可惜的是MS并没有为Silverlight提供一些标准的加密功能实现.如果你想在Silverlight中使用RSA或DES这些标准 ...
- 三菱mode bus tcp通讯_plc以太网通讯模块介绍
PLC以太网通信是基于传统的Ethernet通信机制,使用以太网和TCP/IP协议作为通信基础,在任何场合下都提供对TCP/IP通信的绝对支持.为了能够满足自动化中的实时要求,基于PLC以太网层的优化 ...
最新文章
- 聊聊高并发下的接口幂等性
- R语言:rep函数解析
- 如何在Dart中合并列表
- 图书管理系统c++_校园图书系统写后感
- MySQl求奇数和函数_收集的48个Shell脚本小技巧
- discuz的ajax,discuz分页函数改成基于jqueryd的ajax分页函数
- CAVLC编解码原理与流程
- redis安装包_redis安装与调优部署文档(WinServer)
- 前端开发工程师的定义(转帖)
- 第二百六十三天 how can I 坚持
- 用Windows Live Writer在博客园发布Post
- 处女作:《游戏AI程序设计实战》2019.4.1
- c语言程序设计总结与体会,c语言程序设计个人总结
- BP神经网络算法简介
- 你不知道的“虚假需求”
- 简析市场营销中的六大数据科学用例
- 浪潮服务器安装windows操作系统找不到硬盘、识别不到阵列卡、找不到驱动器,免去各种驱动安装烦恼,浪潮懒人工程师福利
- AngularJS中的$resource使用与Restful资源交互
- 深入分析ELF文件结构及其载入过程
- android webview 拦截响应,android WebView拦截请求详解