首页 > 编程语言 >带你0到1之QT编程:十八、最简单之TCP协议工作原理及实战编程

带你0到1之QT编程:十八、最简单之TCP协议工作原理及实战编程

时间:2024-09-23 11:19:27浏览次数:11  
标签:tcpclient QT appendPlainText pushButton 编程 TCP ui QString MainWindow

此为QT编程的第十八谈!关注我,带你快速学习QT编程的学习路线

每一篇的技术点都是很很重要!很重要!很重要!但不冗余!

我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点!

码农不易,各位学者学到东西请点赞支持支持

开始部分:

总:此次实战主要是实现一个客户端,一个服务端,来了解TCP通信的过程。

分:

一、客户端的实现

1.老规矩,创建一个QMainWindow项目

2.先在.ui文件布局好

3.在.h引入相关头文件

4.在.h文件声明一个客户端专属的socket,相当于电话机,用来通信服务器

5.再声明closeEvent事件,相当于电话机挂号,断开服务器的通信

6.再声明连接函数、断开连接函数、发送消息槽函数的基本功能,再添加一个获取ip地址函数

7.声明完成,就在.cpp进行实现了,首先创建专属的电话机,客户端socket

8.首先实现QComboBox获取本机ip地址的一个功能,就要先实现getlocalip()功能

9.将获取到的ip地址存入QComboBox里面

10.实现连接函数、断开连接函数、发送消息槽函数的基本功能

11.连接信号与槽,当socket连接和断开连接和收到数据的时候触发这些槽函数

12.三个按钮的槽函数实现

13.再将关闭事件实现

14.基础的功能已经完美实现了!发送消息,接收消息,连接,断开连接四个主要的功能,通关qt的信号与槽机制完美实现!

15.需要通过与服务器进行连接检测,检测成功!

二、服务端的实现

1.创建QMainWindow一个项目

2.在.ui布局添加相关控件

3.在.pro添加配置,在.h文件添加相关头文件

4..h文件声明一个QTcpServer对象和一个QTcpSocket对象

5.声明函数和槽函数还有关闭事件

6.先实现四个服务器的基础功能,客户端连接,客户端断开,读取数据,发送数据功能

7.创建一个新连接的槽函数,当有新连接的时候就调用

8.再实现剩下的按钮槽函数

9.实现关闭事件

10.实现最主要的自定义函数来获取本地ip地址

11.在构造函数创建对象和连接槽

12.实现效果如下:

总:无论是客户端还是服务端,实现的基础功能都是四个,建立连接,断开连接,发送数据,接收数据。

客户端的参考源码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //客户端专属socket
    tcpclient=new QTcpSocket(this);

    QString strip=getlocalip();

    ui->comboBox_ip->addItem(strip);

    connect(tcpclient,SIGNAL(connected()),this,SLOT(connectfunc()));
    connect(tcpclient,SIGNAL(disconnected()),this,SLOT(disconnectfunc()));
    connect(tcpclient,SIGNAL(readyRead()),this,SLOT(socketreaddata()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

QString MainWindow::getlocalip()//获取本机ip地址
{
    QString hostname=QHostInfo::localHostName();//获取本地主机名
    QHostInfo hostinfo=QHostInfo::fromName(hostname);//通过主机名获取主机信息

    QString localip="";

    QList<QHostAddress>addlist=hostinfo.addresses();//获取本机的所有ip地址

    if(!addlist.isEmpty())
    {
        for(int i=0;i<addlist.count();i++)
        {
            QHostAddress ahost=addlist.at(i);
            if(QAbstractSocket::IPv4Protocol==ahost.protocol())
            {
                localip=ahost.toString();
                break;
            }
        }
    }
    return localip;
}

void MainWindow::connectfunc()//连接
{
    ui->plainTextEdit_Show->appendPlainText("*********已经连接到服务器端**********");
    ui->plainTextEdit_Show->appendPlainText("************peer address:"+tcpclient->peerAddress().toString());
    ui->plainTextEdit_Show->appendPlainText("************peer port:"+QString::number(tcpclient->peerPort()));
    ui->pushButton_connect->setEnabled(false);
    ui->pushButton_quit->setEnabled(true);
}

void MainWindow::disconnectfunc()//断开连接
{
    ui->plainTextEdit_Show->appendPlainText("************已断开服务端的连接************");
    ui->pushButton_connect->setEnabled(true);
    ui->pushButton_quit->setEnabled(false);
}

void MainWindow::socketreaddata()//读取信息
{
    while(tcpclient->canReadLine())//检查是否有完整的行数据
        ui->plainTextEdit_Show->appendPlainText("输入:"+tcpclient->readLine());
}

void MainWindow::on_pushButton_connect_clicked()//连接服务
{
    QString addr=ui->comboBox_ip->currentText();
    quint16 port=ui->spinBox_port->value();
    tcpclient->connectToHost(addr,port);
}

void MainWindow::on_pushButton_quit_clicked()//停止服务
{
    if(tcpclient->state()==QAbstractSocket::ConnectedState)
        tcpclient->disconnectFromHost();
}

void MainWindow::on_pushButton_send_clicked()//发送消息
{
    QString strmsg=ui->lineEdit_Msg->text();
    ui->plainTextEdit_Show->appendPlainText("输出:"+strmsg);
    ui->lineEdit_Msg->clear();

    QByteArray str=strmsg.toUtf8();
    str.append("\n");
    tcpclient->write(str);//发送数据给服务端
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if(tcpclient->state()==QAbstractSocket::ConnectedState)
    {
        tcpclient->disconnectFromHost();//断开与服务器的连接
    }
    event->accept();
}

服务端的参考源码:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QString strip=GetLocalIpAddress();

    ui->comboBoxIp->addItem(strip);

    tcpserver=new QTcpServer(this);

    connect(tcpserver,SIGNAL(newConnection()),this,SLOT(newconnection()));//存放了基础功能的信号与槽

}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_Start_clicked()//开始服务
{
    QString ip=ui->comboBoxIp->currentText();
    quint16 port=ui->spinBoxPort->value();

    QHostAddress address(ip);
    tcpserver->listen(address,port);

    ui->plainTextEdit_DispMsg->appendPlainText("$$$$$$$$$$开始监听$$$$$$$$$$");
    ui->plainTextEdit_DispMsg->appendPlainText("$$$$$$$$$$服务器地址$$$$$$$$$$:"+
                                               tcpserver->serverAddress().toString());
    ui->plainTextEdit_DispMsg->appendPlainText("$$$$$$$$$$服务器端口$$$$$$$$$$:"+
                                               QString::number(tcpserver->serverPort()));
    ui->pushButton_Start->setEnabled(false);
    ui->pushButton_Stop->setEnabled(true);

}

void MainWindow::on_pushButton_Stop_clicked()//停止服务
{
    if(tcpserver->isListening())
    {
        tcpserver->close();


        tcpsocket->disconnect(); // 加上该关闭套接,服务器停止后,再也无法收到客户端的消息


        ui->pushButton_Start->setEnabled(true);
        ui->pushButton_Stop->setEnabled(false);
    }

}

void MainWindow::on_pushButton_Send_clicked()//发送数据
{
    QString strmsg=ui->lineEdit_InputMsg->text();
    ui->plainTextEdit_DispMsg->appendPlainText("[out]:"+strmsg);

    ui->lineEdit_InputMsg->clear();

    QByteArray str=strmsg.toUtf8();
    str.append("\n");
    tcpsocket->write(str);
}


QString MainWindow::GetLocalIpAddress() // 获取本机的IP地址
{
    QString hostname=QHostInfo::localHostName();
    QHostInfo hostinfo=QHostInfo::fromName(hostname);

    QString localip="";

    QList<QHostAddress> addresslist=hostinfo.addresses();

    if(!addresslist.isEmpty())
    {
        for (int i=0;i<addresslist.count();i++)
        {
            QHostAddress addrhost=addresslist.at(i);
            if(QAbstractSocket::IPv4Protocol==addrhost.protocol())
            {
                localip=addrhost.toString();
                break;
            }

        }
    }

    return localip;
}

void MainWindow::clientconnect()
{
    // 客户端连接
    ui->plainTextEdit_DispMsg->appendPlainText("**********客户端socket连接**********");
    ui->plainTextEdit_DispMsg->appendPlainText("**********peer address:"+
                                               tcpsocket->peerAddress().toString());
    ui->plainTextEdit_DispMsg->appendPlainText("**********peer port:"+
                                               QString::number(tcpsocket->peerPort()));

}

void MainWindow::clientdisconnect()
{
    // 客户端断开连接
    ui->plainTextEdit_DispMsg->appendPlainText("**********客户端socket断开连接**********");
    tcpsocket->deleteLater();

}

void MainWindow::socketreaddata()
{
    // 读取数据
    while(tcpsocket->canReadLine())
        ui->plainTextEdit_DispMsg->appendPlainText("[in]"+tcpsocket->readLine());

}

void MainWindow::newconnection()//存放各种信号与槽
{
    tcpsocket=tcpserver->nextPendingConnection();

    connect(tcpsocket,SIGNAL(connected()),this,SLOT(clientconnect()));
    clientconnect();

    connect(tcpsocket,SIGNAL(disconnected()),this,SLOT(clientdisconnect()));

    connect(tcpsocket,SIGNAL(readyRead()),this,SLOT(socketreaddata()));



}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if(tcpserver->isListening())
        tcpserver->close();

    event->accept();
}

  学习链接:此https://xxetb.xetslk.com/s/3Kif2D

标签:tcpclient,QT,appendPlainText,pushButton,编程,TCP,ui,QString,MainWindow
From: https://blog.csdn.net/weixin_68122199/article/details/142442907

相关文章

  • qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed加
    qDebug()<<"QSslSocket="<<QSslSocket::sslLibraryBuildVersionString();qDebug()<<"OpenSSL支持情况:"<<QSslSocket::supportsSsl();打印需要的版本和当前openssl的支持情况如果显示false,不支持就是说明,不支持加密对应下载版本的openssl进行重新编译即可原因......
  • 【Python高级编程案例】-第1课时-Python 自带邮件模块自动发送邮件
    importrandomimportstringfromsmtplibimportSMTP_SSLfromemail.mime.textimportMIMETextfromemail.headerimportHeader#发送邮件,参数为收件邮箱地址和验证码defsend_email(receiver,code):sender="测试<[email protected]>"#邮箱账号,签名#......
  • Qt C++设计模式->组合模式
    组合模式(CompositePattern)是一种结构型设计模式,允许你将对象组合成树形结构以表示部分与整体的层次关系。组合模式使得客户端可以以统一的方式对待单个对象和组合对象,简化了对复杂树形结构的操作。组合模式的应用场景组合模式非常适合用于需要处理树形结构的场景,比如文件系......
  • 基于Qt的串口调试工具&串口常见问题
    1.项目地址https://github.com/zhangjiechina001/SerialPortTool2.使用注意串口的所有参数波特率、数据位、校验位、停止位、控制流都需要设置正确,设置错了有时会连接上但是传输的数据会很奇怪,有时直接连接不上了串口通信中一般不需要像网络通信那样明确的保活机制(Keep-ali......
  • QTableWidget用法总结
    QTableWidget用法总结直接上代码mainwindow.h#ifndefMAINWINDOW_H#defineMAINWINDOW_H#include<QMainWindow>#include<QDateTime>#include<QScrollBar>#include<QFile>#include<QIODevice>QT_BEGIN_NAMESPACEnamespaceUi{class......
  • shell编程二
    4.3.4.2特殊变量-状态变量1.windows下书写的脚本,脚本文件复制到Linux执行异常的故障案例'''现象:windows下书写的脚本,上传到Linux执行报错.原因:windows下面的回车换行\r\n,linux下面回车换行\n解决:替换结束标记即可.dos2unixwindows-->linux'''[root@ubuntu2204......
  • GUI编程Day01
    GUI编程组件窗口弹窗面板文本框列表框按钮图片监听事件鼠标键盘事件外挂破解工具简介GUI的核心技术:SwingAWT因为界面不美观运行需要jre环境MVC的基础,了解MVC架构,了解监听可以写出自己心中想要的一些小工具工作时候,也可能需要维护到Swing界面,概......
  • Python 客户端类库之paho-mqtt学习总结
    实践环境Python3.9.13paho-mqtt2.1.0简介EclipsePahoMQTTPython客户端类库实现了MQTT协议版本5.0,3.1.1,和3.1。该类库提供一个客户端类,允许应用连接到MQTT代理并发布消息,订阅主题并检索发布的消息。同时还提供了一个写其它辅助函数,使向MQTT服务器发布一次性消息变......
  • 2024睿抗机器人开发者大赛CAIP-编程技能赛-本科组(省赛) RC-u5 工作安排详解
    本文参考https://www.cnblogs.com/Kescholar/p/18306136这一题可能对高手来说就能轻而易举的看出是个01背包,但是对于我这种小白还是要经过详细的分析才可以理解。我们题目要求的是获得的最大报酬,题目的影响因素有三个:工作时长、工作截止时间、对应的报酬,那么怎么样合理的去......
  • 使用Postman测试MQTT协议接口
    MQTT概述MQTT(MessageTelemetryTransport)是一种用于物联网(IoT)的消息传递协议。它的使用范围从家庭自动化和可穿戴设备的小型设备到大型工业机械的自动化。它是一种轻量级技术,以发布/订阅模式为模型,其中连接到单个代理的客户端可以将消息发布到不同的主题,并订阅主题以接收来自......