QtTcpService与QtTcpClient
相关资料:
https://www.cnblogs.com/ybqjymy/p/13683899.html
https://download.csdn.net/download/zhujianqiangqq/20429592 代码包下载
服务端实例:
QtTcpService.pro
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 QT += core gui 2 QT += network 3 4 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 5 6 CONFIG += c++11 7 8 # The following define makes your compiler emit warnings if you use 9 # any Qt feature that has been marked deprecated (the exact warnings 10 # depend on your compiler). Please consult the documentation of the 11 # deprecated API in order to know how to port your code away from it. 12 DEFINES += QT_DEPRECATED_WARNINGS 13 14 # You can also make your code fail to compile if it uses deprecated APIs. 15 # In order to do so, uncomment the following line. 16 # You can also select to disable deprecated APIs only up to a certain version of Qt. 17 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 18 19 SOURCES += \ 20 Server.cpp \ 21 TcpClientSocket.cpp \ 22 Tcpserver.cpp \ 23 main.cpp 24 25 HEADERS += \ 26 Server.h \ 27 TcpClientSocket.h \ 28 Tcpserver.h 29 30 FORMS += \ 31 tcpserver.ui 32 33 # Default rules for deployment. 34 qnx: target.path = /tmp/$${TARGET}/bin 35 else: unix:!android: target.path = /opt/$${TARGET}/bin 36 !isEmpty(target.path): INSTALLS += target
main.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "Tcpserver.h" 2 3 #include <QApplication> 4 5 int main(int argc, char *argv[]) 6 { 7 QApplication a(argc, argv); 8 TcpServer w; 9 w.show(); 10 return a.exec(); 11 }
Tcpserver.h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef TCPSERVER_H 2 #define TCPSERVER_H 3 4 #include <QWidget> 5 #include "Server.h" 6 7 namespace Ui { 8 class TcpServer; 9 } 10 11 class TcpServer : public QWidget 12 { 13 Q_OBJECT 14 15 public: 16 explicit TcpServer(QWidget *parent = 0); 17 ~TcpServer(); 18 19 private slots: 20 void on_CreateChattingRoom_clicked(); 21 void slotupdateserver(QString, int);//接收到server发过来的信号就更新界面的信息 22 private: 23 Ui::TcpServer *ui; 24 int port; 25 Server *server; 26 }; 27 28 #endif // TCPSERVER_H
Tcpserver.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "Tcpserver.h" 2 #include "ui_tcpserver.h" 3 4 TcpServer::TcpServer(QWidget *parent) : 5 QWidget(parent), 6 ui(new Ui::TcpServer) 7 { 8 ui->setupUi(this); 9 port = 8888; 10 } 11 12 TcpServer::~TcpServer() 13 { 14 delete ui; 15 } 16 17 void TcpServer::slotupdateserver(QString msg, int length) 18 { 19 ui->textEdit->append(msg); 20 } 21 22 void TcpServer::on_CreateChattingRoom_clicked() 23 { 24 server = new Server(this, port); 25 connect(server, &Server::updateserver, this, &TcpServer::slotupdateserver); 26 ui->CreateChattingRoom->setEnabled(false); 27 }
Server.h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef SERVER_H 2 #define SERVER_H 3 4 5 #include <QTcpServer> 6 #include <QObject> 7 #include <QList> 8 #include "TcpClientSocket.h" 9 10 class Server : public QTcpServer 11 { 12 Q_OBJECT //为了实现信号和槽的通信 13 public: 14 Server(QObject *parent = 0, int port = 0); 15 QList<TcpClientSocket*> tcpclientsocketlist; 16 protected: 17 void incomingConnection(qintptr socketDescriptor);//只要出现一个新的连接,就会自动调用这个函数 18 protected slots: 19 void sliotupdateserver(QString, int);//用来处理tcpclient发过来的信号 20 void slotclientdisconnect(int); 21 22 signals: 23 void updateserver(QString, int);//发送信号给界面,让界面更新信息 24 }; 25 26 27 #endif // SERVER_H
Server.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "Server.h" 2 #include <QHostAddress> 3 4 Server::Server(QObject *parent, int port):QTcpServer(parent) 5 { 6 listen(QHostAddress::Any, port); //监听 7 } 8 9 void Server::incomingConnection(qintptr socketDescriptor) 10 { 11 TcpClientSocket *tcpclientsocket = new TcpClientSocket(this);//只要有新的连接就生成一个新的通信套接字 12 //将新创建的通信套接字描述符指定为参数socketdescriptor 13 tcpclientsocket->setSocketDescriptor(socketDescriptor); 14 15 //将这个套接字加入客户端套接字列表中 16 tcpclientsocketlist.append(tcpclientsocket); 17 18 19 //接收到tcpclientsocket发送过来的更新界面的信号 20 connect(tcpclientsocket, &TcpClientSocket::updateserver, this, &Server::sliotupdateserver); 21 connect(tcpclientsocket, &TcpClientSocket::clientdisconnected, this, &Server::slotclientdisconnect); 22 23 } 24 25 void Server::sliotupdateserver(QString msg, int length) 26 { 27 //将这个信号发送给界面 28 emit updateserver(msg, length); 29 30 //将收到的信息发送给每个客户端,从套接字列表中找到需要接收的套接字 31 for(int i = 0; i < tcpclientsocketlist.count(); i++) 32 { 33 QTcpSocket *item = tcpclientsocketlist.at(i); 34 // if(item->write((char*)msg.toUtf8().data(), length) != length) 35 // { 36 // continue; 37 // } 38 item->write(msg.toUtf8().data()); 39 } 40 41 } 42 43 void Server::slotclientdisconnect(int descriptor) 44 { 45 for(int i = 0; i < tcpclientsocketlist.count(); i++) 46 { 47 QTcpSocket *item = tcpclientsocketlist.at(i); 48 if(item->socketDescriptor() == descriptor) 49 { 50 tcpclientsocketlist.removeAt(i);//如果有客户端断开连接, 就将列表中的套接字删除 51 return; 52 } 53 } 54 return; 55 }
TcpClientSocket.h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef TCPCLIENTSOCKET_H 2 #define TCPCLIENTSOCKET_H 3 4 5 #include <QTcpSocket> 6 7 class TcpClientSocket : public QTcpSocket 8 { 9 Q_OBJECT //添加这个宏是为了实现信号和槽的通信 10 public: 11 TcpClientSocket(QObject *parent = 0); 12 protected slots: 13 void receivedata();//处理readyRead信号读取数据 14 void slotclientdisconnected();//客户端断开连接触发disconnected信号,这个槽函数用来处理这个信号 15 16 signals: 17 void updateserver(QString, int);//用来告诉tcpserver需要跟新界面的显示 18 void clientdisconnected(int); //告诉server有客户端断开连接 19 }; 20 21 #endif // TCPCLIENTSOCKET_H
TcpClientSocket.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "tcpclientsocket.h" 2 3 TcpClientSocket::TcpClientSocket(QObject *parent) 4 { 5 //客户端发送数据过来就会触发readyRead信号 6 connect(this, &TcpClientSocket::readyRead, this, &TcpClientSocket::receivedata); 7 connect(this, &TcpClientSocket::disconnected, this, &TcpClientSocket::slotclientdisconnected); 8 } 9 10 void TcpClientSocket::receivedata() 11 { 12 // while(bytesAvailable() > 0) 13 // { 14 // int length = bytesAvailable(); 15 // char buf[1024]; //用来存放获取的数据 16 // read(buf, length); 17 // QString msg = buf; 18 // //发信号给界面,让界面显示登录者的信息 19 // emit updateserver(msg, length); 20 // } 21 int length = 10; 22 QByteArray array = readAll(); 23 QString msg = array; 24 emit updateserver(msg, length); 25 } 26 27 void TcpClientSocket::slotclientdisconnected() 28 { 29 emit clientdisconnected(this->socketDescriptor()); 30 }
tcpserver.ui
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <ui version="4.0"> 3 <class>TcpServer</class> 4 <widget class="TcpServer" name="TcpServer"> 5 <property name="geometry"> 6 <rect> 7 <x>0</x> 8 <y>0</y> 9 <width>309</width> 10 <height>334</height> 11 </rect> 12 </property> 13 <property name="windowTitle"> 14 <string>TcpServer</string> 15 </property> 16 <widget class="QLabel" name="label"> 17 <property name="geometry"> 18 <rect> 19 <x>10</x> 20 <y>260</y> 21 <width>271</width> 22 <height>16</height> 23 </rect> 24 </property> 25 <property name="text"> 26 <string>端口:8888</string> 27 </property> 28 </widget> 29 <widget class="QTextEdit" name="textEdit"> 30 <property name="geometry"> 31 <rect> 32 <x>10</x> 33 <y>20</y> 34 <width>281</width> 35 <height>231</height> 36 </rect> 37 </property> 38 </widget> 39 <widget class="QPushButton" name="CreateChattingRoom"> 40 <property name="geometry"> 41 <rect> 42 <x>10</x> 43 <y>280</y> 44 <width>271</width> 45 <height>23</height> 46 </rect> 47 </property> 48 <property name="text"> 49 <string>创建聊天室</string> 50 </property> 51 </widget> 52 </widget> 53 <customwidgets> 54 <customwidget> 55 <class>TcpServer</class> 56 <extends>QWidget</extends> 57 <header>tcpserver.h</header> 58 <container>1</container> 59 </customwidget> 60 </customwidgets> 61 <resources/> 62 <connections/> 63 </ui>
客户端实例:
QtTcpClient.pro
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 QT += core gui 2 QT += network 3 4 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 5 6 CONFIG += c++11 7 8 # The following define makes your compiler emit warnings if you use 9 # any Qt feature that has been marked deprecated (the exact warnings 10 # depend on your compiler). Please consult the documentation of the 11 # deprecated API in order to know how to port your code away from it. 12 DEFINES += QT_DEPRECATED_WARNINGS 13 14 # You can also make your code fail to compile if it uses deprecated APIs. 15 # In order to do so, uncomment the following line. 16 # You can also select to disable deprecated APIs only up to a certain version of Qt. 17 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 18 19 SOURCES += \ 20 TcpClient.cpp \ 21 main.cpp 22 23 HEADERS += \ 24 TcpClient.h 25 26 FORMS += \ 27 TcpClient.ui 28 29 # Default rules for deployment. 30 qnx: target.path = /tmp/$${TARGET}/bin 31 else: unix:!android: target.path = /opt/$${TARGET}/bin 32 !isEmpty(target.path): INSTALLS += target
main.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "TcpClient.h" 2 3 #include <QApplication> 4 5 int main(int argc, char *argv[]) 6 { 7 QApplication a(argc, argv); 8 TcpClient w; 9 w.show(); 10 return a.exec(); 11 }
TcpClient.h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef TCPCLIENT_H 2 #define TCPCLIENT_H 3 4 #include <QWidget> 5 #include <QTcpSocket> 6 7 namespace Ui { 8 class TcpClient; 9 } 10 11 class TcpClient : public QWidget 12 { 13 Q_OBJECT 14 15 public: 16 explicit TcpClient(QWidget *parent = 0); 17 ~TcpClient(); 18 19 private slots: 20 void on_pushButtonEnter_clicked(); 21 void slotconnectedsuccess();//用来处理连接成功的信号 22 void slotreceive();//接收服务器传过来的信息 23 void on_pushButtonSend_clicked(); 24 void slotdisconnected();//用来处理离开聊天室的信号 25 26 27 private: 28 Ui::TcpClient *ui; 29 bool status;//用来判断是否进入了聊天室 30 int port; 31 QHostAddress *serverIP; 32 QString userName; 33 QTcpSocket *tcpsocket; 34 }; 35 36 #endif // TCPCLIENT_H
TcpClient.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "TcpClient.h" 2 #include "ui_tcpclient.h" 3 #include <QHostAddress> 4 #include <QMessageBox> 5 6 TcpClient::TcpClient(QWidget *parent) : 7 QWidget(parent), 8 ui(new Ui::TcpClient) 9 { 10 ui->setupUi(this); 11 //将进入聊天室的标志位置为false 12 status = false; 13 //端口为8888 14 port = 8888; 15 ui->lineEditServerPort->setText(QString::number(port));//界面中端口默认显示8888 16 17 serverIP = new QHostAddress(); 18 19 //未进入聊天室内不能发送信息 20 ui->pushButtonSend->setEnabled(false); 21 } 22 23 TcpClient::~TcpClient() 24 { 25 delete ui; 26 } 27 28 //进入聊天室 29 void TcpClient::on_pushButtonEnter_clicked() 30 { 31 //首先判断这个用户是不是在聊天室中 32 if(status == false) 33 { 34 //不在聊天室中就和服务器进行连接 35 QString ip = ui->lineEditServerIp->text();//从界面获取ip地址 36 if(!serverIP->setAddress(ip))//用这个函数判断IP地址是否可以被正确解析 37 { 38 //不能被正确解析就弹出一个警告窗口 39 QMessageBox::warning(this, "错误", "IP地址不正确"); 40 return; 41 } 42 if(ui->lineEditUserName->text() == "") 43 { 44 //用户名不能为空 45 QMessageBox::warning(this, "错误", "用户名不能为空"); 46 return; 47 } 48 49 //从界面获取用户名 50 userName = ui->lineEditUserName->text(); 51 //创建一个通信套接字,用来和服务器进行通信 52 tcpsocket = new QTcpSocket(this); 53 54 //和服务器进行连接 55 tcpsocket->connectToHost(*serverIP, port); 56 57 //和服务器连接成功能会触发connected信号 58 connect(tcpsocket, &QTcpSocket::connected, this, &TcpClient::slotconnectedsuccess); 59 //接收到服务器的信息就会触发readyRead信号 60 connect(tcpsocket, &QTcpSocket::readyRead, this, &TcpClient::slotreceive); 61 62 63 64 //将进入聊天室的标志位置为true; 65 status = true; 66 } 67 else//已经进入了聊天室 68 { 69 int length = 0; 70 QString msg = userName + ":Leave Chat Room"; 71 // if((length = tcpsocket->write((char*)msg.toUtf8().data(), msg.length())) != msg.length()) 72 // { 73 // return; 74 // } 75 tcpsocket->write(msg.toUtf8().data()); 76 tcpsocket->disconnectFromHost(); 77 status = false; 78 //离开聊天室就会触发disconnected信号 79 connect(tcpsocket, &QTcpSocket::disconnected, this, &TcpClient::slotdisconnected); 80 } 81 } 82 83 //用来处理连接成功的信号 84 void TcpClient::slotconnectedsuccess() 85 { 86 //进入聊天室可以发送信息了 87 ui->pushButtonSend->setEnabled(true); 88 //将进入聊天的按钮改为离开聊天室 89 ui->pushButtonEnter->setText(QStringLiteral("离开聊天室")); 90 91 int length = 0; 92 //将用户名发送给服务器 93 QString msg= userName + " :Enter Chat Room"; 94 95 // if((length = tcpsocket->write((char*)msg.toUtf8().data(), msg.length())) != msg.length()) 96 // { 97 // return; 98 // } 99 tcpsocket->write(msg.toUtf8().data()); 100 } 101 102 103 void TcpClient::slotreceive() 104 { 105 // while(tcpsocket->bytesAvailable() > 0 ) 106 // { 107 // QByteArray datagram; 108 // datagram.resize(tcpsocket->bytesAvailable()); 109 // tcpsocket->read(datagram.data(), datagram.size()); 110 // QString msg = datagram.data(); 111 // ui->textEdit->append(msg.left(datagram.size())); 112 // } 113 QByteArray array = tcpsocket->readAll(); 114 ui->textEdit->append(array); 115 } 116 117 void TcpClient::on_pushButtonSend_clicked() 118 { 119 if(ui->lineEditSend->text() == "") 120 { 121 return; 122 } 123 QString msg = userName + ":" + ui->lineEditSend->text(); 124 // tcpsocket->write((char*)msg.toUtf8().data(), msg.length()); 125 tcpsocket->write(msg.toUtf8().data()); 126 ui->lineEditSend->clear(); 127 } 128 129 void TcpClient::slotdisconnected() 130 { 131 ui->pushButtonSend->setEnabled(false); 132 ui->pushButtonEnter->setText(QStringLiteral("进入聊天室")); 133 }
TcpClient.ui
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <ui version="4.0"> 3 <class>TcpClient</class> 4 <widget class="TcpClient" name="TcpClient"> 5 <property name="geometry"> 6 <rect> 7 <x>0</x> 8 <y>0</y> 9 <width>341</width> 10 <height>463</height> 11 </rect> 12 </property> 13 <property name="windowTitle"> 14 <string>TcpClient</string> 15 </property> 16 <widget class="QPushButton" name="pushButtonSend"> 17 <property name="geometry"> 18 <rect> 19 <x>230</x> 20 <y>300</y> 21 <width>75</width> 22 <height>23</height> 23 </rect> 24 </property> 25 <property name="text"> 26 <string>发送</string> 27 </property> 28 </widget> 29 <widget class="QPushButton" name="pushButtonEnter"> 30 <property name="geometry"> 31 <rect> 32 <x>40</x> 33 <y>430</y> 34 <width>261</width> 35 <height>23</height> 36 </rect> 37 </property> 38 <property name="text"> 39 <string>加入或离开聊天室</string> 40 </property> 41 </widget> 42 <widget class="QTextEdit" name="textEdit"> 43 <property name="geometry"> 44 <rect> 45 <x>20</x> 46 <y>10</y> 47 <width>271</width> 48 <height>281</height> 49 </rect> 50 </property> 51 </widget> 52 <widget class="QLabel" name="label"> 53 <property name="geometry"> 54 <rect> 55 <x>40</x> 56 <y>340</y> 57 <width>54</width> 58 <height>12</height> 59 </rect> 60 </property> 61 <property name="text"> 62 <string>名字:</string> 63 </property> 64 </widget> 65 <widget class="QLabel" name="label_2"> 66 <property name="geometry"> 67 <rect> 68 <x>40</x> 69 <y>370</y> 70 <width>54</width> 71 <height>12</height> 72 </rect> 73 </property> 74 <property name="text"> 75 <string>服务地址:</string> 76 </property> 77 </widget> 78 <widget class="QLabel" name="label_3"> 79 <property name="geometry"> 80 <rect> 81 <x>40</x> 82 <y>400</y> 83 <width>54</width> 84 <height>12</height> 85 </rect> 86 </property> 87 <property name="text"> 88 <string>服务端口:</string> 89 </property> 90 </widget> 91 <widget class="QLineEdit" name="lineEditUserName"> 92 <property name="geometry"> 93 <rect> 94 <x>100</x> 95 <y>340</y> 96 <width>113</width> 97 <height>20</height> 98 </rect> 99 </property> 100 </widget> 101 <widget class="QLineEdit" name="lineEditServerIp"> 102 <property name="geometry"> 103 <rect> 104 <x>100</x> 105 <y>370</y> 106 <width>113</width> 107 <height>20</height> 108 </rect> 109 </property> 110 </widget> 111 <widget class="QLineEdit" name="lineEditServerPort"> 112 <property name="geometry"> 113 <rect> 114 <x>100</x> 115 <y>400</y> 116 <width>113</width> 117 <height>20</height> 118 </rect> 119 </property> 120 </widget> 121 <widget class="QLineEdit" name="lineEditSend"> 122 <property name="geometry"> 123 <rect> 124 <x>20</x> 125 <y>300</y> 126 <width>201</width> 127 <height>20</height> 128 </rect> 129 </property> 130 </widget> 131 </widget> 132 <customwidgets> 133 <customwidget> 134 <class>TcpClient</class> 135 <extends>QWidget</extends> 136 <header>tcpclient.h</header> 137 <container>1</container> 138 </customwidget> 139 </customwidgets> 140 <resources/> 141 <connections/> 142 </ui>
作者:疯狂Delphi
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
欢迎关注我,一起进步!扫描下方二维码即可加我
![](https://images.cnblogs.com/cnblogs_com/FKdelphi/1101510/o_200417075318%E5%8A%A0%E6%88%91QQ.jpg)
![](https://images.cnblogs.com/cnblogs_com/FKdelphi/1101510/o_200417080925%E5%8A%A0%E6%88%91%E5%BE%AE%E4%BF%A1.jpg)