内容简介:参考视频:测试代码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 使用串口通信
- 进程间通信---共享内存
- 微服务通信策略
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
别怕,Excel VBA其实很简单(第2版)
Excel Home / 北京大学出版社 / 2016-7 / 59.00元
对于大部分没有编程基础的职场人士来说,在学习VBA时往往会有很大的畏难情绪。本书正是针对这样的人群,用浅显易懂的语言和生动形象的比喻,并配合大量插画,对Excel中看似复杂的概念和代码,从简单的宏录制、VBA编程环境和基础语法的介绍,到常用对象的操作与控制、执行程序的自动开关—对象的事件、设计自定义的操作界面、调试与优化编写的代码,都进行了形象的介绍。 本书适合那些希望提高工作效率的职场人士......一起来看看 《别怕,Excel VBA其实很简单(第2版)》 这本书的介绍吧!