tcp的聊天室

注意:要加库文件,服务端客户端都要加 network

客户端的头文件

#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_sendbtn_clicked();void on_disconnectbtn_clicked();void on_connectbtn_clicked();
public slots:void connected_slot();void readyRead_slot();void disconnected_slot();private:Ui::Widget *ui;//定义客户端指针QTcpSocket *socket;//定义存储用户名QString username;
};
#endif // WIDGET_H

客户端主函数

#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

 客户端构造函数

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//初始化界面//设置按钮不可以状态ui->msgEdit->setEnabled(false);ui->sendbtn->setEnabled(false);ui->disconnectbtn->setEnabled(false);//给客户端指针实例化空间socket=new QTcpSocket(this);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界面上的ip和端口号QString ip=ui->ipEdit->text();quint16 port =ui->portEdit->text().toUInt();//将客户连接到服务器//参数1:主机地址//参数2:端口号socket->connectToHost(ip,port);//如果成功连接服务器,那么客户端将发送一个conneted信号//我们就可以将该信号连接到自定义的槽函数中处理逻辑代码,由于只需要连接一次,所有我们在构造函数中写连接}void Widget::connected_slot()
{QMessageBox::information(this,"","连接服务器成!");//告诉服务器,用户上线username =ui->userEdit->text();QString msg=username+": 进入聊天室";//将信息发送给服务器socket->write(msg.toLocal8Bit());//将ui界面上的组件进行相关设置//可用状态ui->msgEdit->setEnabled(true);ui->sendbtn->setEnabled(true);ui->disconnectbtn->setEnabled(true);//不可以状态ui->userEdit->setEnabled(false);ui->ipEdit->setEnabled(false);ui->portEdit->setEnabled(false);ui->connectbtn->setEnabled(false);//此时客户端和服务器已经建立连接,如果服务器发来数据,那么客户端就会自动发射 一个readyRead()信号//我们可以将该信号连接到自定义的槽函数中,读取服务器端的数据,又由只需要连接一次,在构造函数写连接}void Widget::readyRead_slot()
{//将服务器端的数据读取出来QByteArray msg =socket->readAll();//将数据放入ui界面上ui->msgWidget->addItem(QString::fromLocal8Bit(msg));
}//disconnected信号对应的槽函数的实现
void Widget::disconnected_slot()
{QMessageBox::information(this,"","断开服务器成功");ui->msgEdit->setEnabled(false);ui->sendbtn->setEnabled(false);ui->disconnectbtn->setEnabled(false);ui->userEdit->setEnabled(true);ui->ipEdit->setEnabled(true);ui->portEdit->setEnabled(true);ui->connectbtn->setEnabled(true);}//发送按钮对应的槽函数
void Widget::on_sendbtn_clicked()
{//获取ui界面上的数据QString msg=ui->msgEdit->text();//整合信息msg=username+":"+msg;//将数据发送给服务器socket->write(msg.toLocal8Bit());//清空发送框里的内容ui->msgEdit->clear();
}//端口服务器按钮的槽函数处理
void Widget::on_disconnectbtn_clicked()
{//告诉大家我走了QString msg =username+":离开聊天室";//信息发送给服务器socket->disconnectFromHost();//如果成功与服务器断开连接,那么该客户端就会自动发送一个disconnected信号//我们就可以将该信号连接到自定义函数中,处理逻辑代码,由于只要连接一次,所有在构造函数中连接
}

客户端ui界面

 

服务端头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>
#include <QList> //链表容器
#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_staetBtn_clicked();void newConnection_solt(); //newconnection信号对应的槽函数void readyRead_slot();private:Ui::Widget *ui;//定义服务器指针QTcpServer *server;//定义客户端容器QList<QTcpSocket *> socketList;};
#endif // WIDGET_H

服务端主函数

#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

服务的构造函数

#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_staetBtn_clicked()
{//获取ui界面上的端口号quint16 port = ui->portEdit->text().toInt();//将服务器设置监听状态//函数原型:bool//参数1:主机地址 可以是任意//参数2:端口号if(server->listen(QHostAddress::Any,port)){QMessageBox::information(this,"","启动服务器成功!");}else{QMessageBox::information(this,"","启动服务器失败!");}//此时说明服务器已经进入监听状态,如果有客户端发来连接请求,那么服务器端就会自动发射newconnection//将该信号连接到自定义的槽函数中,获取客户端的套接字connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_solt);
}//newConnection信号对应槽函数处理
void Widget::newConnection_solt()
{qDebug() <<"有新的用户连接" ;//获取最新连接的客户端套接字//函数原型:virtual QTcpSocket *nextPendingConnection();//返回值:是客户端套接字的指针QTcpSocket *s =server->nextPendingConnection();//将套接字放入容器中socketList.push_back(s);//程序运行至此,说明服务端和客户端已经建立起联系,如果客户端发来数据,那么客户端就会自动发射readyrRead()信号//我们就可以将信号连接自定义的槽函数中,读取客户端的数据connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);}
//readyRead信号对应槽函数声明
void Widget::readyRead_slot()
{//移除无效客户端//count :在容器中的所有元素个数for(int i=0;i<socketList.count();i++){//函数原型:socketstate state() constif(socketList.at(i)->state()==0){//移除socketList.removeAt(i);//将下表为i的 客户端移除}}//遍历有效客户端,寻找哪个客户端有数据待读for (int i=0;i<socketList.count();i++){//函数原型://判断是否有数据if(socketList.at(i)->bytesAvailable()!=0){//读取套接字中的数据QByteArray msg = socketList.at(i)->readAll();//将数据放在ui界面上ui->msgWidget->addItem(QString::fromLocal8Bit(msg));//将数据广播给(发送)给所有客户端for(int j=0;j<socketList.count();j++){//将数据写入到套接字中socketList.at(j)->write(msg);}}}
}

服务端ui界面

 

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

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

相关文章

人工智能导论习题集(3)

第五章&#xff1a;不确定性推理 题1题2题3题4题5题6题7题8 题1 题2 题3 题4 题5 题6 题7 题8

搜维尔科技:第九届元宇宙数字人设计大赛校园行讲演活动正式启动—中国戏曲学院站!

由全国高等院校计算机基础教育研究会指导&#xff0c;利亚德集团和爱迪斯通科技发起的数字人设计大赛正在火热进行中&#xff0c;同时进行的元宇宙数字人设计大赛校园行活动也正式拉开序幕&#xff0c;12月13日校园行活动—中国戏曲学院开讲。划重点&#xff1a;此次大赛已成为…

CNN 卷积神经网络之 DenseNet 网络的分类统一项目(包含自定义数据集的获取)

1. DenseNet 网络介绍 本章实现的项目是DenseNet 网络对花数据集的五分类&#xff0c;下载链接&#xff1a; 基于迁移学习的 DenseNet 图像分类项目 DenseNet 网络是在 ResNet 网络上的改进&#xff0c;大概的网络结构如下&#xff1a; 1.1 卷积的简单介绍 图像识别任务主要…

BearPi Std 板从入门到放弃 - 先天神魂篇(3)(RT-Thread I2C设备)

简介 使用BearPi IOT Std开发板及其扩展板E53_SC1&#xff0c; SC1上有I2C1 的光照强度传感器BH1750 和 EEPROM AT24C02&#xff0c; 本次主要就是读取光照强度; 主板: 主芯片: STM32L431RCT6LED : PC13 \ 推挽输出\ 高电平点亮串口: Usart1I2C使用 : I2C1E53_SC1扩展板 : LE…

蓝牙物联网全屋智能系统解决方案

#蓝牙物联网# 蓝牙物联网全屋智能系统解决方案是一种通过低功耗蓝牙技术将家中的各种设备连接到一起&#xff0c;实现家居物联智能操控的方案。 全屋智能系统解决方案是一种将智能家居设备、传感器、照明、安防等系统集成在一起&#xff0c;实现全屋智能化控制的方案。 蓝牙物…

Excel: Python 如何干掉 VBA 系列 乙

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/k2XtfXS3GUt4r2QhizMOVg 创建工作表格 创建表格 xlwings 就可以协助创建插入了宏的 excel 表格。 先找到一个心满意足的目录&#xff0c;一般我…

webpack详细教程

1&#xff0c;什么是webpackwebpack | webpack中文文档 | webpack中文网 Webpack 不仅是一个模块打包器(bundler)&#xff0c;更完整的讲是一个前端自动化构建工具。在 Webpack 看来前端的所有资源文件(s/json/css/img/less/...)都会作为横块处理它将根据模块的依赖关系进行静…

mysql数据库相关知识【MYSQL】

mysql数据库相关知识【MYSQL】 一. 库1.1 登录数据库管理系统1.2 什么是数据库1.2.1 mysqld与mysql 1.3 编码集和校验集1.3.1 什么是编码集和校验集1.3.2 查看库对应的编码集和校验集1.3.3 用指定的编码集和校验集 1.4 库的操作 一. 库 1.1 登录数据库管理系统 这个算是第一个…

节流防抖:提升前端性能的秘密武器(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

浅谈基于深度学习的手写体纸质文档识别OCR软件

引言&#xff1a; 随着数字化时代的到来&#xff0c;纸质文档的电子化需求越来越强烈。在众多的OCR&#xff08;Optical Character Recognition&#xff09;软件中&#xff0c;基于深度学习的手写体纸质文档识别OCR软件成为了关注焦点。本文将探讨这种软件的特点、功能以及应用…

基于SSM架构的超市管理系统设计

基于SSM架构的超市管理系统设计 目录 基于SSM架构的超市管理系统设计 1 环境及工具1.1 IDEA软件安装1.2 JDK环境配置1.3 MySQL数据库安装1.3.1常规情况1.3.2非常规情况 1.4 Tomcat安装 2 部署与设计2.1 数据库信息创建2.2项目创建与部署 3 相关说明4 功能操作说明4.1 管理员操作…

互联网加竞赛 python opencv 深度学习 指纹识别算法实现

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python opencv 深度学习 指纹识别算法实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;4分创新点&#xff1a;4分 该项目较为新颖…

SE考研真题总结(三)

继续更新&#xff0c;今天准备连出两期该系列~ SE考研真题总结&#xff08;二&#xff09;https://blog.csdn.net/jsl123x/article/details/134857052?spm1001.2014.3001.5501 目录 一.简答题 二.代码大题 一.简答题 1.工程和科学的区别 科学是关于事物的基本原理和事实的…

计算4*4*4空间中2点结构的分布

不考虑两点距离的情况下&#xff0c;3维空间中的两点最多只有7种位置关系。3条边&#xff0c;3条面对角线&#xff0c;1条体对角线。现在向4*4*4的3维空间中随机的扔2个石子&#xff0c;比较7种结构的占比。 得到表格为 1 96 0.0476 2 96 0.0476 3 288 0.1429 4 288 …

【ARM Trace32(劳特巴赫) 使用介绍 6 -- 通用寄存器查看与修改】

请阅读【Trace32 ARM 专栏导读】 文章目录 通用寄存器查看与修改Rester 命令语法Register.InitRegister.RELOAD高亮显示Register变化的值多核寄存器显示设置寄存器的值修改 通用寄存器查看与修改 在使用Trace32进行调试时&#xff0c;有时候需要查看并修改通用寄存器、PC指针、…

使用ffmpeg命令进行视频格式转换

1 ffmpeg介绍 FFmpeg 是一个非常强大和灵活的开源工具集&#xff0c;用于处理音频和视频文件。它提供了一系列的工具和库&#xff0c;可以用于录制、转换、流式传输和播放音频和视频。 FFmpeg 主要特点如下&#xff1a; 格式支持广泛&#xff1a;FFmpeg 支持几乎所有的音频和视…

ARM开发基础知识

1、ARM寄存器 概念&#xff1a;寄存器是处理器内部的存储器&#xff0c;没有地址 作用&#xff1a;一般用于暂时存储参与运算的数据和运算结果 分类&#xff1a;通用寄存器、专用寄存器、状态寄存器 注意&#xff1a;有标签&#xff08;带三角光标&#xff09;的是独有的寄存器…

Caché/M 数据库上面的那个 é 怎么打

Cach/M 数据库名字上的 e 有一撇&#xff0c;这个 e 是法语字符&#xff0c;通常英语键盘还不是那么好打。 因最近在研究这个数据库&#xff0c;所以这个字符会用得比较多&#xff0c;简单点的方法就是直接用 e 代替&#xff0c;并且后面加个斜杆 M 用于区分英文的 Cache。 拷…

几本学习中整理和面试的PDF,以及精选面试资料

今天和大家分享我在学习过程中整理的笔记&#xff0c;以及我在准备面试中&#xff0c;阅读的PDF&#xff0c;包括Spring Cloud学习手册、Docker学习手册、RabbitMQ学习手册、Spring 6手册、Maven手册、22w字面试手册等等&#xff0c;包括了大部分后端技术以及大部分高频面试题&…

计算机网络应用层(期末、考研)

计算机网络总复习链接&#x1f517; 目录 DNS域名服务器域名解析过程分类递归查询&#xff08;给根域名服务器造成的负载过大&#xff0c;实际中几乎不用&#xff09;迭代查询 域名缓存&#xff08;了解即可&#xff09;完整域名解析过程采用UDP服务 FTP控制连接与数据连接 电…