内容简介:参考视频:测试代码github:说明:本文介绍Qt下实现tcp客户端和服务器通信的过程。
1 简介
参考视频: https://www.bilibili.com/video/BV1XW411x7NU?p=56
测试代码github: https://github.com/zhengcixi/Qt_Demo/tree/master/tcp
说明:本文介绍Qt下实现tcp客户端和服务器通信的过程。
Linux下tcp客户端和服务器通信模型可参考我的另一篇博客: https://www.cnblogs.com/mrlayfolk/p/11968446.html 。Qt下tcp通信的原理是一样的。
Qt的TCP通信模型如下:
(1)TCP服务器端
1)创建服务器套接字,使用QTcpServer()类;
2)将套接字设置为监听模式;
3)等待客户端连接请求,客户端连接上时会触发newConnection信号,可调用nextPendingConnection函数获取客户端的Socket信息;
4)和客户端进行通信,发送数据可使用write()函数,接收数据可使用read()或readAll函数()。
(2)TCP客户端
1)创建套接字;
2)连接服务器,使用connectToHost()函数;
3)和服务器进行通信,发送数据可使用write()函数,接收数据可使用read()或readAll函数()。
2 测试说明
功能说明:分别创建两个窗口,一个用作TCP服务器端,一个用作TCP客户端,双方进行通信。窗口如下:
服务器窗口: 客户端窗口:
下面分别说明代码实现的步骤:
(1)服务器端
首先创建两个套接字指针。tcpserver用作服务器套接字,tcpsocket用作和客户端通信的通信套接字。
1 QTcpServer *tcpserver = NULL; //监听套接字 2 QTcpSocket *tcpsocket = NULL; //通信套接字
然后,创建套接字并启动监听。
1 //监听套接字,指定父对象,自动回收空间 2 tcpserver = new QTcpServer(this); 3 //启动监听 4 tcpserver->listen(QHostAddress::Any, 8888);
捕捉newConnect信号与槽函数,等待客户端连接:
1 //等待连接 2 connect(tcpserver, &QTcpServer::newConnection, 3 [=]() { 4 //取出建立好连接的套接字 5 tcpsocket = tcpserver->nextPendingConnection(); 6 //获取对方的ip的端口 7 QString ip = tcpsocket->peerAddress().toString(); 8 qint16 port = tcpsocket->peerPort(); 9 QString tmp = QString("[%1:%2]:成功连接").arg(ip).arg(port); 10 //在当前对话框显示谁和我连接了 11 ui->textEdit_recv->setText(tmp); 12 } 13 );
发送数据:
1 //获取编辑区内容 2 QString str = ui->textEdit_send->toPlainText(); 3 //给对方发送数据 4 //QString -> char* 5 tcpsocket->write(str.toUtf8().data());
接收数据:
1 //接收数据 2 connect(tcpsocket, &QTcpSocket::readyRead, 3 [=](){ 4 //从通信套接字中取出内容 5 QByteArray array = tcpsocket->readAll(); 6 ui->textEdit_recv->append(array); 7 } 8 );
关闭连接:
1 //主动和客户端断开连接 2 tcpsocket->disconnectFromHost(); 3 tcpsocket->close(); 4 tcpsocket = NULL;
(2)客户端
客户端只需要创建一个套接字,用于和服务器建立连接并通信:
1 QTcpSocket *tcpsocket = NULL; //通信套接字 2 //分配空间,指定父对象 3 tcpsocket = new QTcpSocket(this);
和服务器端建立连接:
1 //获取服务器ip和端口 2 QString ip = ui->lineEdit_ip->text(); 3 qint16 port = ui->lineEdit_port->text().toInt(); 4 //主动和服务器建立连接 5 tcpsocket->connectToHost(QHostAddress(ip), port);
发送数据:
1 //获取编辑框内容 2 QString str = ui->textEdit_send->toPlainText(); 3 //发送数据 4 tcpsocket->write(str.toUtf8().data());
接收数据:
1 connect(tcpsocket, &QTcpSocket::readyRead, 2 [=](){ 3 //获取对方发送的内容 4 QByteArray array = tcpsocket->readAll(); 5 //追加到编辑区中 6 ui->textEdit_recv->append(array); 7 } 8 );
断开连接:
1 //主动和对方断开连接 2 tcpsocket->disconnectFromHost(); 3 tcpsocket->close();
(3)完整的工程代码:
工程所包含的文件有,serverwidget.cpp和serverwidget.h是服务器端的代码,clientwidget.cpp和clientwidget.h是客户端代码。
serverwidget.cpp代码:
1 #include "serverwidget.h" 2 #include "ui_serverwidget.h" 3 4 ServerWidget::ServerWidget(QWidget *parent) : 5 QWidget(parent), 6 ui(new Ui::ServerWidget) 7 { 8 ui->setupUi(this); 9 setWindowTitle("服务器: 8888"); 10 11 //监听套接字,指定父对象,自动回收空间 12 tcpserver = new QTcpServer(this); 13 //启动监听 14 tcpserver->listen(QHostAddress::Any, 8888); 15 //等待连接 16 connect(tcpserver, &QTcpServer::newConnection, 17 [=]() { 18 //取出建立好连接的套接字 19 tcpsocket = tcpserver->nextPendingConnection(); 20 //获取对方的ip的端口 21 QString ip = tcpsocket->peerAddress().toString(); 22 qint16 port = tcpsocket->peerPort(); 23 QString tmp = QString("[%1:%2]:成功连接").arg(ip).arg(port); 24 //在当前对话框显示谁和我连接了 25 ui->textEdit_recv->setText(tmp); 26 27 //接收数据 28 connect(tcpsocket, &QTcpSocket::readyRead, 29 [=](){ 30 //从通信套接字中取出内容 31 QByteArray array = tcpsocket->readAll(); 32 ui->textEdit_recv->append(array); 33 } 34 ); 35 } 36 ); 37 } 38 39 ServerWidget::~ServerWidget() 40 { 41 delete ui; 42 } 43 44 45 void ServerWidget::on_pushButton_close_clicked() 46 { 47 if (NULL == tcpsocket) { 48 return; 49 } 50 //主动和客户端断开连接 51 tcpsocket->disconnectFromHost(); 52 tcpsocket->close(); 53 tcpsocket = NULL; 54 } 55 56 void ServerWidget::on_pushButton_send_clicked() 57 { 58 if (NULL == tcpsocket) { 59 return; 60 } 61 //获取编辑区内容 62 QString str = ui->textEdit_send->toPlainText(); 63 //给对方发送数据 64 //QString -> char* 65 tcpsocket->write(str.toUtf8().data()); 66 } View Code
serverwidget.h代码:
1 #ifndef SERVERWIDGET_H 2 #define SERVERWIDGET_H 3 4 #include <QWidget> 5 #include <QTcpServer> //监听套接字 6 #include <QTcpSocket> //通信套接字 7 8 namespace Ui { 9 class ServerWidget; 10 } 11 12 class ServerWidget : public QWidget 13 { 14 Q_OBJECT 15 16 public: 17 explicit ServerWidget(QWidget *parent = 0); 18 ~ServerWidget(); 19 20 private slots: 21 void on_pushButton_send_clicked(); 22 23 void on_pushButton_close_clicked(); 24 25 private: 26 Ui::ServerWidget *ui; 27 QTcpServer *tcpserver = NULL; //监听套接字 28 QTcpSocket *tcpsocket = NULL; //通信套接字 29 }; 30 31 #endif // SERVERWIDGET_H View Code
clientwidget.cpp代码:
1 #include "clientwidget.h" 2 #include "ui_clientwidget.h" 3 #include <QHostAddress> 4 5 clientwidget::clientwidget(QWidget *parent) : 6 QWidget(parent), 7 ui(new Ui::clientwidget) 8 { 9 ui->setupUi(this); 10 setWindowTitle("客户端"); 11 //分配空间,指定父对象 12 tcpsocket = new QTcpSocket(this); 13 //建立连接 14 connect(tcpsocket, &QTcpSocket::connected, 15 [=]() { 16 ui->textEdit_recv->setText("成功和服务器建立了连接"); 17 } 18 ); 19 //接收数据 20 connect(tcpsocket, &QTcpSocket::readyRead, 21 [=](){ 22 //获取对方发送的内容 23 QByteArray array = tcpsocket->readAll(); 24 //追加到编辑区中 25 ui->textEdit_recv->append(array); 26 } 27 ); 28 //断开连接 29 connect(tcpsocket, &QTcpSocket::disconnected, 30 [=](){ 31 ui->textEdit_recv->append("和服务器断开了连接"); 32 } 33 ); 34 } 35 36 clientwidget::~clientwidget() 37 { 38 delete ui; 39 } 40 41 void clientwidget::on_pushButton_send_clicked() 42 { 43 //获取编辑框内容 44 QString str = ui->textEdit_send->toPlainText(); 45 //发送数据 46 tcpsocket->write(str.toUtf8().data()); 47 } 48 49 void clientwidget::on_pushButton_close_clicked() 50 { 51 //主动和对方断开连接 52 tcpsocket->disconnectFromHost(); 53 tcpsocket->close(); 54 } 55 56 void clientwidget::on_pushButton_connect_clicked() 57 { 58 //获取服务器ip和端口 59 QString ip = ui->lineEdit_ip->text(); 60 qint16 port = ui->lineEdit_port->text().toInt(); 61 //主动和服务器建立连接 62 tcpsocket->connectToHost(QHostAddress(ip), port); 63 } View Code
clientwidget.h代码:
1 #ifndef CLIENTWIDGET_H 2 #define CLIENTWIDGET_H 3 4 #include <QWidget> 5 #include <QTcpSocket> 6 7 namespace Ui { 8 class clientwidget; 9 } 10 11 class clientwidget : public QWidget 12 { 13 Q_OBJECT 14 15 public: 16 explicit clientwidget(QWidget *parent = 0); 17 ~clientwidget(); 18 19 private slots: 20 void on_pushButton_send_clicked(); 21 22 void on_pushButton_close_clicked(); 23 24 void on_pushButton_connect_clicked(); 25 26 private: 27 Ui::clientwidget *ui; 28 QTcpSocket *tcpsocket = NULL; 29 }; 30 31 #endif // CLIENTWIDGET_H View Code
main.cpp代码,启动两个窗口:
1 #include "serverwidget.h" 2 #include <QApplication> 3 #include "clientwidget.h" 4 5 int main(int argc, char *argv[]) 6 { 7 QApplication a(argc, argv); 8 ServerWidget w; 9 clientwidget w2; 10 w.show(); 11 w2.show(); 12 13 return a.exec(); 14 } View Code
运行进行测试:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 网络通信2:TCP简单通信
- 网络通信3:TCP交互通信
- 如何在ASP.NET Core中使用SignalR构建与Angular通信的实时通信应用程序
- Electron 使用串口通信
- 进程间通信---共享内存
- 微服务通信策略
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
算法竞赛入门经典
刘汝佳、陈锋 / 2012-10 / 52.80元
《算法竞赛入门经典:训练指南》是《算法竞赛入门经典》的重要补充,旨在补充原书中没有涉及或者讲解得不够详细的内容,从而构建一个较完整的知识体系,并且用大量有针对性的题目,让抽象复杂的算法和数学具体化、实用化。《算法竞赛入门经典:训练指南》共6章,分别为算法设计基础、数学基础、实用数据结构、几何问题、图论算法与模型和更多算法专题,全书通过近200道例题深入浅出地介绍了上述领域的各个知识点、经典思维方式......一起来看看 《算法竞赛入门经典》 这本书的介绍吧!
XML、JSON 在线转换
在线XML、JSON转换工具
html转js在线工具
html转js在线工具