2023/10/4 QT实现TCP服务器客户端搭建

服务器端:

头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QList>
#include <QMessageBox>
#include <QDebug>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();void readyRead_slot();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);//1.实力化一个服务器server = new QTcpServer(this);//此时服务器已经成功进入监听状态,如果客户端向服务器发来连接请求//那么服务器就会自动发射一个newconnection信号,可以在该信号连接到对应的槽函数作出相应处理//3.由于只需要连接一次即可,所以可以将该连接放在构造函数中完成connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);}Widget::~Widget()
{delete ui;
}//启动服务器按钮对应的槽函数
void Widget::on_startbtn_clicked()
{//获取ui界面上的端口号quint16 port = ui->portedit->text().toInt();//2.监听客户端的连接请求if(!server->listen(QHostAddress::Any,port)){QMessageBox::information(this,"失败","监听失败");return ;}else{QMessageBox::information(this,"成功","服务器启动成功");}}//自定义处理newconnection信号的槽函数实现
void Widget::newConnection_slot()
{qDebug()<<"您有新的客户端发来连接请求了";//4.获取最新连接的客户端套接字QTcpSocket *s = server->nextPendingConnection();//将该套接字放入客户端链表中clientlist.push_back(s);//如果客户端发来数据,对应的客户端套接字就会自动发射一个readyRead信号//4.可以将该信号连接到自定义的槽函数中,处理对应的逻辑connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
}//readyRead信号对应槽函数的实现
void Widget::readyRead_slot()
{qDebug()<<"有新的客户端消息发来";//遍历客户端链表,将无效的客户端移除for(int i=0;i<clientlist.size();i++){if(clientlist[i]->state()==0){//将该套接字移除客户端容器clientlist.removeAt(i);}}//遍历客户端链表,判断是那个客户端发来的数据for(int i=0;i<clientlist.size();i++){//bytesAvalilable函数,功能:求当前客户端套接字中待读数据的字节数//返回值:字节数,如果是0,表示无数据待读if(clientlist[i]->bytesAvailable()!=0){//将待读的数据读取出来QByteArray msg = clientlist[i]->readAll();//将数据展示到ui界面上ui->msgwidget->addItem(QString::fromLocal8Bit(msg));//将接收到的数据据,转发给所有客户端for(int j=0;j<clientlist.size();j++){clientlist[j]->write(msg);}}}}

ui界面

客户端:

头文件:

#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();//自定义处理conneced信号的槽函数void connected_slot();void readyRead_slot();void on_sendbtn_clicked();void on_disconnectbtn_clicked();void disconnected_slot();
private:Ui::Widget *ui;//定义客户端指针QTcpSocket *socket;//定义字符串接收用户名QString userName;
};
#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);//当成功与服务器断开连接后,该客户端会自动发射一个disconned的信号//connect(socket,&QTcpSocket::disconnected,this,&Widget::disconnected_slot);
}Widget::~Widget()
{delete ui;
}//连接服务器按钮定义的槽函数
void Widget::on_connectbtn_clicked()
{//获取ui界面上的相关信息userName =ui->username_edit->text(); //获取用户名QString ip =ui->ip_edit->text();     //主机地址quint16 port =ui->port_edit->text().toUInt(); //端口号//将客户端连接到给定的服务器socket->connectToHost(ip,port);}
//处理conneced信号的槽函数的定义
void Widget::connected_slot()
{QMessageBox::information(this,"成功","您已经成功进入聊天室");//向服务器发送一条数据:***进入聊天室QString msg = userName + "进入聊天室";socket->write(msg.toLocal8Bit()); //将数据写给服务器
}//处理readyRead信号的槽函数的定义
void Widget::readyRead_slot()
{//读取套接字中的信息QByteArray msg = socket->readAll();//将数据展示到ui界面ui->msgWidget->addItem(QString::fromLocal8Bit(msg));
}//发送按钮对应的槽函数
void Widget::on_sendbtn_clicked()
{//获取ui界面输入的内容QString msg = userName+":"+ui->edit1->text();//发送给服务器socket->write(msg.toLocal8Bit());
}
//断开服务器按钮对应的槽函数
void Widget::on_disconnectbtn_clicked()
{//告诉大家我走了QString msg =userName +":离开聊天室";socket->write(msg.toLocal8Bit());//断开连接socket->disconnectFromHost();}//disconnected信号对应槽函数的定义
void Widget::disconnected_slot()
{QMessageBox::information(this,"退出","退出成功");
}

ui界面

效果图

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

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

相关文章

Flutter AI五子棋

前言 在上一篇文章中&#xff0c;讲解了如何实现双人在本地对战的五子棋&#xff0c;但是只有一个人的时候就不太好玩&#xff0c;同时博主也没有把五子棋相关的文章写过瘾。那么这篇文章&#xff0c;我们来实现一个功能更加丰富的五子棋吧&#xff01;在设计五子棋的算法方面&…

竞赛 机器视觉人体跌倒检测系统 - opencv python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 机器视觉人体跌倒检测系统 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&…

JVM篇---第三篇

系列文章目录 文章目录 系列文章目录一、什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?二、Java内存结构三、说说对象分配规则一、什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文…

C#捕捉全局异常

1.运行图片 2.源码 using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms;namespace 捕捉全局异常 {internal static class Program{/// <summary>/// 应用程序的主入口点。/// </summary…

【算法|动态规划No.9】leetcodeLCR 091. 粉刷房子

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

MongoDB数据库网站网页实例-编程语言Python+Django

程序示例精选 PythonDjangoMongoDB数据库网站网页实例 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《PythonDjangoMongoDB数据库网站网页实例》编写代码&#xff0c;代码整洁&#xff0c;…

波奇学C++:AVL树

AVL解决二叉搜索树退化成链表&#xff0c;保证左右子树高度不差过1&#xff0c;尽可能接近满二叉树 AVL树的性质&#xff1a;高度差&#xff08;平衡因子&#xff09;的绝对值不超过1&#xff08;-1/0/1&#xff09; 平衡因子&#xff1a;右子树高度-左子树高度 用平衡因子控…

【计算机网络】HTTPS协议详解

文章目录 一、HTTPS协议 介绍 1、1 HTTP协议不安全的体现 1、2 什么是 HTTPS协议 二、加密的一些概念 2、1 怎么理解加密 2、2 为什么要加密 2、3 常见的加密方式 2、2、1 对称加密 2、2、2 非对称加密 三、HTTPS协议探究加密过程 3、1 只使用对称加密 3、2 只是用非对称加密 3…

javaee spring整合mybatis

案例一 包含dao层 创建maven webapp项目 maven仓库需要改为阿里云 引入依赖 <?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-inst…

HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Badge

可以附加在单个组件上用于信息标记的容器组件。该组件从API Version 7开始支持。 支持单个子组件。子组件类型&#xff1a;系统组件和自定义组件&#xff0c;支持渲染控制类型&#xff08;if/else、ForEach和LazyForEach&#xff09;。 一、接口 方法1&#xff1a; Badge(value…

【MySql】Mysql之备份与恢复

目录 一、mysql日志概述 1、日志类型与作用 2、日志配置文件 3、日志配置文件的查询 二、备份的类型❤ 1、物理备份 1.1 冷备份 1.2 热备份 1.3 温备份 2、逻辑备份❤ 2.1 完全备份 2.2 差异备份 2.3 增量备份 2.5 如何选择逻辑备份策略 3、常见的备份方法 3…

ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM dirty RAM)并以Cortex-A55示例

Cortex-A55 MESI 状态获取 一&#xff0c;系统寄存器以及读写指令二&#xff0c;Cortex-A55 Data cache的MESI信息获取&#xff08;AARCH 64&#xff09;2.1 将Set/way信息写入Data Cache Tag Read Operation Register2.2 读取Data Register 1和Data Register 0数据并解码 参考…