目录

QT之TCP网络通信保姆级教程超详细解说

QT之TCP网络通信——保姆级教程(超详细解说)

目录


一.TCP基础知识(了解)

1.TCP的概念

TCP(Transmission Control Protocol)——是一种用于在计算机网络中传输数据的协议。它是一种可靠的、面向连接的协议,确保数据在传输过程中不会丢失、损坏或者乱序。

TCP通过建立连接、数据传输、数据确认和连接关闭等步骤来保证数据的可靠传输。

TCP是互联网中最常用的传输层协议之一,它与IP(Internet Protocol)共同组成了TCP/IP协议栈,用于实现数据的可靠传输和网络通信。

2.实现TCP网络通信的条件

要实现TCP网络通信,通常需要以下条件:

  1. IP地址:每个设备都需要有一个唯一的IP地址,用于在网络中进行通信。

  2. 端口号:TCP通信需要使用端口号来区分不同的应用程序或服务。

  3. TCP协议栈:操作系统中集成了TCP/IP协议栈,用于实现TCP通信。

  4. 网络连接:设备之间需要通过网络连接(如局域网、互联网)来进行通信。

虽然通常情况下,TCP通信需要一个服务器(server)和一个客户端(client)来进行通信,服务器负责监听连接请求并处理客户端的请求,客户端则负责向服务器发送请求并接收服务器的响应。但也可以通过模拟客户端和服务器之间的通信来进行测试或演示,以便于调试和开发。

二.使用QT进行TCP模拟通信

在上面我们也说了,TCP通信需要一个服务器(server)和一个客户端(client)来进行通信。

所以在QT中我们主要创建一个Server(服务器)窗口和一个Client(客户端)窗口来进行通信。

也就是说,我们要在QT中建立两个文档,一个是Server,一个是Client。

一. 服务器窗口

1.添加库和头文件

在QT的帮助里面搜索QTcpServer和QTcpSocket,可以看到:

https://i-blog.csdnimg.cn/blog_migrate/52fbd062936c1d24e459da02c9cf5baf.png

https://i-blog.csdnimg.cn/blog_migrate/c1253a5448b407a7290f69f11cde72eb.png

图中的Header后的#include和#include是我们需要在QT中添加的头文件,qmake后的QT+=network是我们需要添加的QT模块。

让我们新建一个文档。

打开QT ——>进入欢迎界面——>在该界面中点击 Project 旁边的 +New——>项目选择Application的Qt Widgets Application——>点击右下侧的choose按钮继续——>名称自己随便起,为了方便标识,建议设置成TCP_Server——>然后选择路径,继续点击下一步——>Define Build System就选默认的qmake即可,继续——>进入Class Information中,Base class选择QWidget,其他名称会自动改变,当然这里你也可以自己设置一个名字,继续——>进入Translation File,不做改变,继续——>进入Kit Selection,这里选默认即可,继续——>进入 Project Management,在当前界面可以看到我们创建这个文件之后,将要添加的问价,最后点击完成。

https://i-blog.csdnimg.cn/blog_migrate/45347506adb8a51edd0195c846ee98c4.png

https://i-blog.csdnimg.cn/blog_migrate/e9371ccd0063ad1f15136460935da013.png

https://i-blog.csdnimg.cn/blog_migrate/965a3c1ad111c5dba3e02ae9e9b716bf.png

https://i-blog.csdnimg.cn/blog_migrate/74b14b32acb0813de51505760aadb99e.png

https://i-blog.csdnimg.cn/blog_migrate/23828307dfe2d02594c026000f99c043.png

https://i-blog.csdnimg.cn/blog_migrate/bf40a17ddd1f2ec61b04ec7d7c1abafe.png

https://i-blog.csdnimg.cn/blog_migrate/fda21bcba226589004b63361846586a5.png

https://i-blog.csdnimg.cn/blog_migrate/bf6e07c190aec138e721e303dbdd5416.png

这里默认是32位,但是如果电脑是64位并且安装了64位的系统,建议选择64位。

https://i-blog.csdnimg.cn/blog_migrate/b0b0aed2311817c2f53463da6a69d792.png

https://i-blog.csdnimg.cn/blog_migrate/5e15409c9245184415edb913b297ed8c.png 最后点击完成,就新建了一个文档,接下来我们将对该文档进行一系列编辑,来实现服务器的功能。

首先进入TCP_Server.pro文档中,在右侧代码界面中的         QT        += core gui 后加上 network。

https://i-blog.csdnimg.cn/blog_migrate/4ec89b1b2983c79c0a2bd6a8e46ea2ef.png

https://i-blog.csdnimg.cn/blog_migrate/4bac8d5c5ff7b4504e02f7a945735c81.png

接着进入widget.h头文件中,添加头文件:#include ,#include ,在这之前一定要先添加network模版。

https://i-blog.csdnimg.cn/blog_migrate/ecca745ae07d022eab944a44e97ba58e.png

编译后没有问题,进入下一步。

2.布局

进入widget.ui界面中,开始布局。

https://i-blog.csdnimg.cn/blog_migrate/c3b7c64865a2556a5ece8dad2788eed8.png

https://i-blog.csdnimg.cn/blog_migrate/b0afe622d275ebfa421ccbf47ea3050a.png

为了方便编程,我们给各个Edit改下名字。

https://i-blog.csdnimg.cn/blog_migrate/ead9bee8f64cb515b6c620f2e7a3e9c3.png

其中接收窗口——recvEdit、发送窗口——sendEdit、打开服务器按钮——openBt、关闭服务器按钮——closeBt、发送——sendBt。

3.实例化

在widget.h文件中声明对象和槽函数。

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>    //添加的头文件
#include <QTcpSocket>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;    //添加的对象
    QTcpServer *tcpServer;
    QTcpSocket *tcpSocket;

private slots:
    void newConnection_Slot();    //添加的槽函数
    void readyRead_Slot();
    void on_openBt_clicked();
    void on_closeBt_clicked();
    void on_sendBt_clicked();

};
#endif // WIDGET_H

接着在widget.cpp中初始化和撰写槽函数。

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("Server");

    tcpServer = new QTcpServer(this);
    tcpSocket = new QTcpSocket(this);

    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnection_Slot()));
}

void Widget::newConnection_Slot()    //连接槽函数
{
    tcpSocket=tcpServer->nextPendingConnection();
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
}

void Widget::readyRead_Slot()    //读取数据槽函数
{
    QString buf;
    buf=tcpSocket->readAll();
    ui->recvEdit->appendPlainText(buf);
}

Widget::~Widget()    //析构函数
{
    delete ui;
}

void Widget::on_openBt_clicked()    //打开按钮按下
{
    tcpServer->listen(QHostAddress::Any,ui->portEdit->text().toUInt());
}

void Widget::on_closeBt_clicked()    //关闭按钮按下
{
    tcpServer->close();
}

void Widget::on_sendBt_clicked()    //发送按钮按下
{
    tcpSocket->write(ui->sendEdit->text().toUtf8());
}

到此为止,服务器窗口建立完毕,下面,我们开始建立客户端窗口。

二. 客户端窗口

1.添加库和头文件

添加的步骤和服务器制作相同。

在pro文件中添加 network。

在widget.h头文件中添加 #include

注意,这里只需要添加QTcpSocket,不需要添加QTcpServer了。

2.布局

进入widget.ui界面中,开始布局。

https://i-blog.csdnimg.cn/blog_migrate/fec70b86e72b7e54409215616658cb81.png

https://i-blog.csdnimg.cn/blog_migrate/85c778315454b6d5b780579e635c333e.png

和上面一样,为了方便编程,改一下每一个Edit的名字。

https://i-blog.csdnimg.cn/blog_migrate/9e771a3d99b3b080b050d193f81ff5d1.png

其中,接收框——recvEdit、端口号——portEdit、IP——IPEdit、发送框——sendBt、打开客户端、关闭客户端、发送按钮分别对应——openBt、closeBt、sendBt。

3.实例化

进入widget.h文件中,声明对象和槽函数。

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>    //添加的头文件

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;    //声明对象
    QTcpSocket *tcpSocket;

private slots:
    void connected_Slot();    //声明槽函数
    void readyRead_Slot();
    void on_openBt_clicked();
    void on_closeBt_clicked();
    void on_sendBt_clicked();
};
#endif // WIDGET_H

进入widget.cpp文件中开始初始化和撰写槽函数。

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowTitle("Client");

    tcpSocket= new QTcpSocket(this); 
}

void Widget::connected_Slot()    //连接槽函数
{
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
}

void Widget::readyRead_Slot()    //读取数据槽函数
{
    ui->recvEdit->appendPlainText(tcpSocket->readAll());
}

Widget::~Widget()    //析构函数
{
    delete ui;
}

void Widget::on_openBt_clicked()    //打开按钮按下
{
    tcpSocket->connectToHost(ui->IPEdit->text(),ui->portEdit->text().toUInt());
    connect(tcpSocket,SIGNAL(connected()),this,SLOT(connected_Slot()));
}

void Widget::on_closeBt_clicked()    //关闭按钮按下
{
    tcpSocket->close();
}

void Widget::on_sendBt_clicked()    //发送按钮按下
{
    tcpSocket->write(ui->sendEdit->text().toUtf8());
}

到此为止,客户端窗口制作完毕,下面我们来进行验证。

三.验证

1.首先运行Server窗口,得到

https://i-blog.csdnimg.cn/blog_migrate/65f65fdfaa048684a4e6ce038e8171b8.png

2.接着运行Client窗口,得到

https://i-blog.csdnimg.cn/blog_migrate/ff01473777aa6b79ffb60250474d91bd.png

3.测试一下它们的发送和接收功能吧!!

首先可以回到电脑桌面,按住电脑的win+r键,输入cmd,接着输入IPConfig,可以看到

https://i-blog.csdnimg.cn/blog_migrate/42366666563b55451e06e1b9140835b8.png

复制一下其中的IPv4地址,如果有多个,复制第一个即可。

在上面的图中,IPv4地址就为:192.168.124.39

然后回到QT中,将该地址粘贴到Client的IP中,端口号填写1234即可,要保证Client的端口号和Server的端口号是相同的。

https://i-blog.csdnimg.cn/blog_migrate/2ac703bfbdc5be95900dbd51997ceff6.png

https://i-blog.csdnimg.cn/blog_migrate/702c1d453b638c10c04191988ca560fa.png

填写好后,按下Client中的打开客户端按钮和Server中的打开服务器按钮,然后就可以开始发送数据啦!!!

https://i-blog.csdnimg.cn/blog_migrate/93948b7312d8a6aeebcef18a348a74a0.png

当然,这还只是最基础的功能,我甚至还有很多地方是比较粗糙,不够完善的,后续有机会,会继续完善,希望对你有帮助!!