当前位置: 首页 > news >正文

day5 QT

作业

客户端

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), socket(new QTcpSocket(this))//给客户端指针实例化空间
{ui->setupUi(this);//初始化界面ui->send_btn->setEnabled(false);ui->msg_edit->setEnabled(false);ui->disconnect_btn->setEnabled(false);//如果客户端成功连接服务器,那么客户端自动发射一个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_connect_btn_clicked()
{//获取ui界面上的ip和端口号QString ip = ui->ip_edit->text();quint16 port = ui->port_edit->text().toUInt();//让客户端连接服务器//connectToHost(const QString &hostName, quint16 port, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);//参数1:连接服务器的IP地址//参数2:连接服务器的端口号socket->connectToHost(ip,port);
}void Widget::connected_slot()
{username = ui->username_edit->text();//告诉服务器,客户端已连接QString msg = username + ":进入聊天室";//将信息发送给服务器socket->write(msg.toLocal8Bit());ui->send_btn->setEnabled(true);ui->msg_edit->setEnabled(true);ui->disconnect_btn->setEnabled(true);ui->username_edit->setEnabled(false);ui->ip_edit->setEnabled(false);ui->port_edit->setEnabled(false);ui->connect_btn->setEnabled(false);}//发送按钮对应的槽函数
void Widget::on_send_btn_clicked()
{//获取ui界面输入框中的文本QString msg = username + ":" + ui->msg_edit->text();//将信息发送给服务器socket->write(msg.toLocal8Bit());//申请单独列表项用于显示自己发的信息QListWidgetItem *item = new QListWidgetItem();//申请标签存放自己的信息,并设置标签对齐方式为右对齐QLabel *label = new QLabel(ui->msg_edit->text(),this);label->setAlignment(Qt::AlignRight);//添加列表项ui->listWidget->addItem(item);//设置label作为新添加列表项的显示内容ui->listWidget->setItemWidget(item,label);//清空输入框ui->msg_edit->clear();
}void Widget::readyRead_slot()
{//读取服务器发来的数据QByteArray msg = socket->readAll();//将读取到的信息放入ui界面上ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}//断开连接按钮对应的槽函数
void Widget::on_disconnect_btn_clicked()
{//告诉服务器,我走了QString msg = username + ":" + "离开聊天室";socket->write(msg.toLocal8Bit());//断开与服务器的连接socket->disconnectFromHost();}//成功与服务器断开连接后执行的槽函数
void Widget::disconnected_slot()
{ui->send_btn->setEnabled(false);ui->msg_edit->setEnabled(false);ui->disconnect_btn->setEnabled(false);ui->username_edit->setEnabled(true);ui->ip_edit->setEnabled(true);ui->port_edit->setEnabled(true);ui->connect_btn->setEnabled(true);
}

服务器端

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), server(new QTcpServer(this))//给服务器指针实例化空间
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}//启动按钮槽函数
void Widget::on_start_btn_clicked()
{//获取ui界面的端口号quint16 port = ui->port_edit->text().toUInt();//将字符串转换成整形//服务器设置监听//bool server->listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)//监听成功返回true,失败返回falseif(server->listen(QHostAddress::Any,port)){//监听成功QMessageBox::information(this,"提示","启动服务器成功");//成功后按钮不可按ui->start_btn->setEnabled(false);}else{//监听失败QMessageBox::information(this,"","启动服务器失败");return;}//程序至此,说明监听成功,如果客户端发来连接请求,那服务器就会自动发射一个newConnection()信号//我们就可以将该信号连接到自定义的槽函数中,处理相关逻辑代码connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);}//槽函数的实现
void Widget::newConnection_slot()
{qDebug() << "有新的客户端连接...";//获取最新连接的客户端的套接字QTcpSocket *s = server->nextPendingConnection();//将客户端放入客户端容器中socketList.push_back(s);//此时说明客户端和服务器已经建立了连接,如果客户端向服务器端发来数据,那么客户端就会自动发射一个readyRead()信号//我们就可以将该信号连接到自定义的槽函数中,读取客户端的数据connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);}//readyRead对应的槽函数
void Widget::readyRead_slot()
{//读取客户端的数据//遍历客户端容器,移除无效客户端//容器里的元素个数for(int i=0; i<socketList.count(); i++){//判断客户端和服务器的连接状态//为连接状态的枚举值是 0if(socketList.at(i)->state() == 0){//移除无效客户端socketList.removeAt(i);}//遍历客户端容器,判断哪个客户端有数据待读for(int i=0; i< socketList.count(); i++){//判断哪个客户端有数据带读//qint64 bytesAvailable() const override;//接收数据的字节大小if(socketList.at(i)->bytesAvailable() != 0){//读取数据QByteArray msg = socketList.at(i)->readAll();//将读取到的数据放到ui界面上ui->listWidget->addItem(QString::fromLocal8Bit(msg));//将数据广播给所有客户端for(int j=0; j<socketList.count(); j++){if(j != i){socketList.at(j)->write(msg);}}}}}
}

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 多级缓存的设计与实现
  • C语言代码练习(第十八天)
  • ​如何使用QGIS制作三维建筑
  • 一张图告诉你常见的响应状态码!200报错400 404 500都是什么意思??
  • 光耦合器的工作原理和故障诊断
  • 25. MyBatis中的RowBounds是什么?如何实现内存分页?
  • KAN 学习 Day4 —— MultKAN 正向传播代码解读及测试
  • 【RabbitMQ】概述
  • 骨传导耳机哪个品牌比较好?盘点五款闭眼入都不踩雷的优质骨传导耳机!
  • 大模型LLM之SpringAI:Web+AI(一)
  • UEFI学习笔记(七):UEFI_Spec_2_10 Protocols整理
  • 【滑动窗口-1004. 最大连续1的个数 III】
  • 基于Java+SpringBoot+Vue+MySQL的西安旅游管理系统网站
  • Windows--linux共享文件夹
  • SAP B1 学习笔记 - 易混淆字段名(持续更新中)
  • [case10]使用RSQL实现端到端的动态查询
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • Android Volley源码解析
  • Angular 2 DI - IoC DI - 1
  • AWS实战 - 利用IAM对S3做访问控制
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • ES6--对象的扩展
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • leetcode-27. Remove Element
  • Puppeteer:浏览器控制器
  • Vue.js-Day01
  • 从PHP迁移至Golang - 基础篇
  • 回顾2016
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 正则表达式
  • Semaphore
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • # 数据结构
  • #Linux(权限管理)
  • $.each()与$(selector).each()
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (zt)最盛行的警世狂言(爆笑)
  • (补充)IDEA项目结构
  • (第27天)Oracle 数据泵转换分区表
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (五)activiti-modeler 编辑器初步优化
  • (转)scrum常见工具列表
  • (转载)从 Java 代码到 Java 堆
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .net打印*三角形
  • @RequestBody与@ModelAttribute
  • @Transactional 详解