QTday5(QT连接TCP通信)

一、Xmind整理:

C语言中的通信协议:

二、上课笔记整理:

1.QT中的服务器端的操作:

.pro文件:

头文件:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>   //服务器头文件
#include <QTcpSocket>   //客户端头文件
#include <QList>        //链表头文件,用来存放客户端文件
#include <QDebug>
#include <QMessageBox>  //消息对话框类QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_startBtn_clicked();void newConnection_slot();             //自定义处理readRead信号的槽函数void readyRead_slot();                  //自定义处理readRead信号的槽函数private:Ui::Widget *ui;//定义服务器指针QTcpServer *server;//定义客户端指针链表容器QList<QTcpSocket *> clientList;};
#endif // WIDGET_H

源文件:

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//给服务器指针实例化对象server = new QTcpServer(this);        //此时就创建了一个服务器}Widget::~Widget()
{delete ui;
}//启动服务器按钮对应的槽函数
void Widget::on_startBtn_clicked()
{//获取ui界面上的端口号quint16 port = ui->portEdit->text().toUInt();//将服务器设置成监听状态//bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)//参数1:要监听的主机地址,如果是any,表示监听所有主机地址,也可以给特定的主机地址进行监听//参数2:通过指定的端口号进行访问服务器,如果是0,表示由服务器自动分配,如果非0,则表示指定端口号//返回值:成功返回真,失败返回假if(!server->listen(QHostAddress::Any,port)){QMessageBox::critical(this,"失败","服务器启动失败");}else{QMessageBox::information(this,"启动成功","等待客户端连接中...");}//此时表明服务器启动成功,并对客户端连接进行监听//如果有客户端向服务器发来连接请求,那么该服务器就会发射一个newConnection的信号//我们可以将该信号连接到对应的槽函数中处理相关逻辑connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);
}//处理newConnection信号的槽函数的实现
void Widget::newConnection_slot()
{qDebug() << "有新的客户端发来连接请求了...";//获取最新连接的客户端套接字//函数原型:[virtual] QTcpSocket *QTcpServer::nextPendingConnection()//参数:无//返回值:最新连接客户端套接字的指针QTcpSocket *s = server->nextPendingConnection();//将获取的套接字存放到客户端容器中clientList.push_back(s);//此时,客户端就和服务器建立起来联系了//如果该套接字有数据项服务器发送过来,那么该套接字就会自动发射一个readyRead信号//我们可以将该信号连接到自定义的槽函数中处理相关逻辑connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);}//关于readyRead信号对应槽函数的实现
void Widget::readyRead_slot()
{//删除客户端链表中的无效客户端套接字for(int i = 0; i < clientList.count(); i++){//判断套接字的状态//函数原型:SocketState state() const;//功能:返回客户端套接字的状态//参数:无//返回值:客户端的状态,如果结果为0,表示未连接if(clientList[i]->state() == 0){clientList.removeAt(i);    //将下标为i的客户端移除掉`}}//遍历所有客户端,查看是哪个客户端发来数据表for(int i = 0 ; i < clientList.count(); i++){//函数原型:qint64 bytesAvailable() const override;//功能:返回当前客户端套接字中的可读数据字节个数//参数:无//返回值:当前客户端待读的字节数,如果该数据为0,表示无待读数据if(clientList[i]->bytesAvailable() != 0){//读取当前客户端的相关数据//函数原型:QByteArray readAll();//功能:读取当前套接字中的所有数据,并返回一个字节数组//参数:无//返回值:数据的字节数组QByteArray msg = clientList[i]->readAll();//将数据展示到ui界面上ui->msgList->addItem(QString::fromLocal8Bit(msg));//将接受到的该消息,发送给所有的客户端for(int j = 0; j < clientList.count(); j++){clientList[j]->write(msg);}}}}

2.QT中的客户端的操作:

.pro文件:

头文件:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpSocket>     //客户端头文件
#include <QMessageBox>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_connectBtn_clicked();void connected_slot();                //自定义处理connected信号的槽函数void readyRead_slot();                //自定义处理readRead信号的槽函数void on_sendBtn_clicked();void on_disConnectBtn_clicked();void disconnected_slot();              //自定义处理disconnected信号的槽函数private:Ui::Widget *ui;//定义一个客户端指针QTcpSocket *socket;QString userName;         //用户名QString *hostName;
};
#endif // WIDGET_H

源文件:

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 给客户端指针实例化空间socket = new QTcpSocket(this);//如果连接服务器成功,该客户端就会发射一个connected的信号//我们可以将该信号连接到自定义的槽函数中处理相关逻辑//由于该连接只需连接一次,所以,写在构造函数中即可connect(socket, &QTcpSocket::connected, this, &Widget::connected_slot);//客户端与服务器连接成功后,如果服务器向客户端发来数据,那么该客户端就会自动发射一个readyRead信号//我们可以将该信号connect(socket,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);//当客户端与服务器断开连接后,该客户端就会自动发射一个disconnected的信号//我们可以将该信号与自定义的槽函数连接//由于该连接只需连接一次,所以,写在构造函数中即可connect(socket,&QTcpSocket::disconnected,this,&Widget::disconnected_slot);}Widget::~Widget()
{delete ui;
}//连接服务器按钮对应的槽函数
void Widget::on_connectBtn_clicked()
{//获取ui界面的信息userName = ui->userNameEdit->text();         //获取用户名QString hostName = ui->ipEdit->text();       //获取主机地址quint16 port = ui->portEdit->text().toUInt(); //获取端口号//调用函数连接到主机//函数原型:[virtual] void QAbstractSocket::connectToHost(const QString &hostName, quint16 port)//参数1:服务器的主机地址//参数2:端口号//返回值:无socket->connectToHost(hostName,port);//如果连接服务器成功,该客户端就会发射一个connected的信号//我们可以将该信号连接到自定义的槽函数中处理相关逻辑//由于该连接只需连接一次,所以,写在构造函数中即可}//关于处理connected信号的槽函数的定义
void Widget::connected_slot()
{QMessageBox::information(this,"成功","连接服务器成功");//顺便向服务器发送一条消息,说:xxx进入聊天室QString msg = userName + "进入聊天室";socket->write(msg.toLocal8Bit());
}//关于readyRead信号对应槽函数的实现
void Widget::readyRead_slot()
{//读取该客户端中的数据QByteArray msg = socket->readAll();//将数据展示在ui界面ui->msgList->addItem(QString::fromLocal8Bit(msg));
}//发送按钮对应的槽函数
void Widget::on_sendBtn_clicked()
{//获取ui界面中的编辑的文本内容QString m = ui->msgEdit->text();//整合要发送的信息QString msg = userName + ":" + m;//将消息发送给服务器socket->write(msg.toLocal8Bit());//将消息编辑框中的内容情况ui->msgEdit->clear();}//断开服务器按钮对应的槽函数
void Widget::on_disConnectBtn_clicked()
{//准备要发送的信息QString msg = userName + ":离开聊天室";socket->write(msg.toLocal8Bit());//调用成员函数disconnectFromHost//函数原型:virtual void disconnectFromHost();//功能:断开客户端与服务器的连接//参数:无//返回值:无socket->disconnectFromHost();//当客户端与服务器断开连接后,该客户端就会自动发射一个disconnected的信号//我们可以将该信号与自定义的槽函数连接//由于该连接只需连接一次,所以,写在构造函数中即可
}//
void Widget::disconnected_slot()
{QMessageBox::information(this,"退出"," 断开成功");}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/126854.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式 - 责任链

一、前言 ​ 相信大家平时或多或少都间接接触过责任链设计模式&#xff0c;只是可能有些同学自己不知道此处用的是该设计模式&#xff0c;比如说 Java Web 中的 Filter 过滤器&#xff0c;就是非常经典的责任链设计模式的例子。 那么什么是责任链设计模式呢&#xff1f; ​ …

Android studio 实现生成二维码和扫描二维码

效果图 build.gradle(:app)添加依赖 dependencies {implementation com.google.zxing:core:3.3.3implementation com.journeyapps:zxing-android-embedded:3.6.0implementation com.google.zxing:javase:3.0.0 }Manifests.xml <uses-permission android:name"android…

FastStone Capture

FastStone Capture 简介下载安装注册 简介 FastStone Capture是一款用于屏幕截图和屏幕录制的工具。它允许用户捕捉屏幕上的内容&#xff0c;并将其保存为图像文件&#xff0c;还可以录制屏幕活动为视频文件。 FastStone Capture官网: https://www.faststone.org/FSCaptureDet…

手写Spring:第2章-创建简单的Bean容器

文章目录 一、目标&#xff1a;创建简单的Bean容器二、设计&#xff1a;创建简单的Bean容器三、实现&#xff1a;创建简单的Bean容器3.0 引入依赖3.1 工程结构3.2 创建简单Bean容器类图3.3 Bean定义3.4 Bean工厂 四、测试&#xff1a;创建简单的Bean容器4.1 用户Bean对象4.2 单…

go-zero直连与etcd服务注册中心

go-zero中直连方式 在使用grpc是最重要的就是pb文件了&#xff0c;生成的pb文件&#xff0c;通过pb文件可以生成grpc的客户端和服务端&#xff0c;那么客户端和服务端就可以直连了&#xff0c;再次基础上可以引入etcd实现服务注册。 所有的代码都需要开发者编写&#xff0c;包…

Stable Diffuse 之 本地环境部署 WebUI 进行汉化操作

Stable Diffuse 之 本地环境部署 WebUI 进行汉化操作 目录 Stable Diffuse 之 本地环境部署 WebUI 进行汉化操作 一、简单介绍 二、汉化操作 附录&#xff1a; 一、Install from URL 中出现 Failed to connect to 127.0.0.1 port 7890: Connection refused 错误&#xf…

基于微信小程序美食菜品预订点餐预约系统uniapp+vue

点餐预约系统主要是为了提高用户的工作效率和更方便快捷的满足用户&#xff0c;更好存储所有数据信息及快速方便的检索功能&#xff0c;对点餐预约系统的各个模块是通过许多今天的发达点餐预约系统做出合理的分析来确定考虑用户的可操作性&#xff0c;遵循开发的系统优化的原则…

网络安全概述

从今天开始&#xff0c;我将开启一个网络安全的小课堂&#xff0c;分享一些网络安全方面的相关知识点&#xff0c;大家可以一起学习&#xff0c;争取对网络安全、网络攻防有一定的认识&#xff0c;今天是第一讲网络安全概述&#xff0c;来简单介绍一下网络安全。 1 网络安全的…

数据结构零基础入门篇(C语言实现)

前言&#xff1a;数据结构属于C学习中较难的一部分&#xff0c;对应学习者的要求较高&#xff0c;如基础不扎实&#xff0c;建议着重学习C语言中的指针和结构体&#xff0c;万丈高楼平地起。 目录&#xff1a; 一&#xff0c;链表 1&#xff09;单链表的大致结构实现 2&…

IDEA插件Mybatis Log Plugin的安装及其使用教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 插件概述 Mybatis Log Plugin插件用于查看Mybatis所执行的完整SQL语句。在此教程中详细介绍IDEA插件Mybatis Log Plugin的安装及其使用。 安装过程 请搜索并安装Mybatis …

强大的JTAG边界扫描(3):常用边界扫描测试软件

文章目录 1. 功能强大的XJTAG2. 小巧简洁的TopJTAG3. TopJTAG安装4. TopJTAG基本使用 本文介绍两款常用的边界扫描测试软件&#xff1a;XJTAG和TopJTAG&#xff0c;前者收费、功能强大&#xff0c;后者免费&#xff08;和谐后&#xff09;&#xff0c;功能简洁。 如果只是要进…

springdoc-openapi-ui 整合 knife,多模块分组,脚手架

pom文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.o…

【VS Code插件开发】常见自定义命令(七)

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域优质作者、阿里云专家博主&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4e2; 资料领取&#xff1a;前端…

FANUC机器人电气控制柜内部硬件电路和模块详细介绍

FANUC机器人电气控制柜内部硬件电路和模块详细介绍 PSU电源单元 通过背板传输了如下电源 +5 +2.0V +3.3 +24v +24E +15V -15V 主板--接口描述: 主板内部结构: 面板电路板: 引申一下 KM21 与 KM22 的作用它们分别接至操作面板上上的急停按

分库分表实战

数据分片与分片算法 分库分表的第一性原理&#xff0c;那就是&#xff1a;存储容量和性能容量。只有对核心业务表才会精心进行分库分表的设计。 首先我们了解一下数据分片是什么意思&#xff1f; 本质上的分库分表不就是数据分片吗&#xff1f;定义就是&#xff1a;按照某个…

Flask狼书笔记 | 05_数据库

文章目录 5 数据库5.1 数据库的分类5.2 ORM5.3 使用Flask_SQLAlchemy5.4 数据库操作5.5 定义关系5.6 更新数据库表5.7 数据库进阶小结 5 数据库 这一章学习如何在Python中使用DBMS&#xff08;数据库管理系统&#xff09;&#xff0c;来对数据库进行管理和操作。本书使用SQLit…

算法通关村14关 | 堆在数组中找第k大的元素应用

1. 在数组中找第k大元素 题目 LeetCode215&#xff1a;给定整数数组nums和整数k&#xff0c;请返回数组中第k个最大的元素&#xff0c; 思路 解题思路用三个&#xff0c;选择法&#xff0c;堆查找和快速排序。 我们选择用大堆小堆解决问题&#xff0c;“找最大用小堆&#xff…

【JS面试题】如何通过闭包漏洞在外部修改函数中的变量

✍️ 作者简介: 前端新手学习中。 &#x1f482; 作者主页: 作者主页查看更多前端教学 &#x1f393; 专栏分享&#xff1a;css重难点教学 Node.js教学 从头开始学习 ajax学习 前端面试题 文章目录 什么是闭包例 如何在函数外部修改闭包中变量 什么是闭包 闭包这个东西对新…

animate.css与vue中的v-if/v-show如何一起使用

第一步:在已有的vue项目中安装animate.css npm install animate.css --save第二步&#xff1a;在 main.js 引入 import animate.css第三步&#xff1a;如果在vue中使用了v-if 或者v-show 的话就不能直接在元素上加入animate的class。我们应该在v-if/v-show的元素外层添加tran…

一个新工具 nolyfill

名字的意思&#xff0c; 我自己的理解 no(po)lyfill 正如它的名字, 不要再用补丁了, 当然这里说的是过时的补丁。 polyfill 是补丁的意思 为什么要用这个插件 文档原文: 当您通过安装最新的 Node.js LTS 来接受最新的功能和安全修复时&#xff0c;像eslint-plugin-import、…