基于QTcpSocket和QTcpServer的Tcp通讯以及QDataStream序列化数据
来源:互联网 发布:ubuntu进不去系统 编辑:程序博客网 时间:2024/06/05 08:36
这里涉及到几个问题:
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_Motor13 {14 int length;15 int command;16 QString data;17 };18 19 20 class Motor21 {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 QMainWindow68 {69 Q_OBJECT70 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 //out103 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 QMainWindow14 {15 Q_OBJECT16 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 Motor16 {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 QTcpServer50 {51 Q_OBJECT52 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
- 基于QTcpSocket和QTcpServer的Tcp通讯以及QDataStream序列化数据
- QTcpServer和QTcpSocket的使用
- qt4 tcp QTcpSocket QTcpServer 传输数据
- QTcpServer与QTcpSocket通讯
- 使用QTcpSocket和QTcpServer进行TCP编程
- QT 使用QTcpServer QTcpSocket 建立TCP服务器端 和 客户端
- 关于QT中用QTcpserver 和QTcpsocket接收和发送数据的一个规则理解
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- QTcpSocket类和QTcpServer类
- QTcpSocket QTcpServer 类的使用方法
- Qt网络编程QTcpServer和QTcpSocket的理解
- Qt网络编程QTcpServer和QTcpSocket的理解
- 【java学习】Servlet简单的表单程序(一)
- linux环境编程之多线程同步
- ubuntu12.10下OpenFoam的编译
- Android项目2之横屏和竖屏切换
- AccessToMySql数据库的导入以及java生成.exe文件
- 基于QTcpSocket和QTcpServer的Tcp通讯以及QDataStream序列化数据
- 使用struts2自定义拦截器,要引入defaultStack
- 将博客搬至CSDN
- 4.2 指令集介绍
- Django知识点总结(二)
- 文本框和密码框长度不一致 解决办法
- j2se学习笔记-异常处理
- 我也来CSDN写博客了。
- Spring3 MVC详解一