4/11 QT_day5

news2024/11/27 21:03:42

服务器端

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QMessageBox>
#include <QTcpSocket>
#include <QList>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_startBtn_clicked();
public slots:
    void newConnection_slot();
    void readyRead_slot();
private:
    Ui::Widget *ui;
    QTcpServer *ser;
    QList<QTcpSocket*> socketlist;
};
#endif // WIDGET_H

源文件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    , ser(new QTcpServer(this))
{
    ui->setupUi(this);
}

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


void Widget::on_startBtn_clicked()
{
    //获取ui界面上的端口号
    quint16 port = ui->portEdit->text().toUInt();//将字符串转换成整形(仅限纯数字字符串)
    //让服务器设置监听

    if(ser->listen(QHostAddress::Any,port) == true)
    {
        //监听成功,跳出对话框
        QMessageBox::information(this,"","启动服务器成功");
        //服务器如果发来连接请求,那么服务器就会自动发射一个连接请求
        //那么就可以将该信号连接到自定义的槽函数中,处理逻辑代码
    }
    else
    {
        //监听失败
        QMessageBox::critical(this,"","启动服务器失败");

        return;
    }
    connect(ser,&QTcpServer::newConnection,this,&Widget::newConnection_slot);

}
//newConnection信号对应的槽函数
void Widget::newConnection_slot()
{
    //获取最新连接的客户端的套接字
    QTcpSocket *s = ser->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++)
    {
        //功能:判断客户端与服务器的连接状态
        //如果未连接,未连接的枚举对应的值为0
        if(socketlist.at(i)->state() == 0)
        {
            socketlist.removeAt(i);
        }
    }
    //便利容器 那个客户端有数据待读
    for(int i = 0;i<socketlist.count();i++)
    {
        //bytesAvailable()返回字节大小
        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++)
            {
                socketlist.at(j)->write(msg);
            }
        }
    }
}

服务器端

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_connectBtn_clicked();
    void on_disconnectBtn_clicked();

    void on_SendBtn_clicked();

public slots:
    void connected_slot();
    void readRead_slot();
    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)
    , socket(new QTcpSocket)
{
    ui->setupUi(this);//设置不可用
    ui->msgEdit->setEnabled(false);
    ui->SendBtn->setEnabled(false);
    ui->disconnectBtn->setEnabled(false);
    //如果连接成功到服务器,客户端会发送一个connect()函数
    connect(socket,&QTcpSocket::connected,this,&Widget::connected_slot);
}

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


void Widget::on_connectBtn_clicked()
{
    QString ip = ui->ipEdit->text();
    quint16 port = ui->portEdit->text().toUInt();
    //客户端连接服务器
    socket->connectToHost(ip,port);

}

void Widget::connected_slot()
{
    //成功连接到服务器
    //提示服务器已上线
    //组织想发送的语言
    username = ui->UserNameEdit->text();
    QString msg = username+":进入聊天室";
    //将数据发送至服务器
    socket->write(msg.toLocal8Bit());
    //服务器和客户端成功建立连接
    ui->msgEdit->setEnabled(true);
    ui->SendBtn->setEnabled(true);
    ui->disconnectBtn->setEnabled(true);
    ui->connectBtn->setEnabled(false);

    //如果服务端向客户端发来数据,那么客户端会自动发射一个readyRead()信号
    connect(socket,&QTcpSocket::readyRead,this,&Widget::readRead_slot);
}

void Widget::readRead_slot()
{
    //读取数据
    QByteArray msg = socket->readAll();
    //将读取到的数据写到ui界面上
    ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}



void Widget::on_SendBtn_clicked()
{
    //获取ui界面上的内容
    QString msg = ui->msgEdit->text();
    //组织语言
    msg = username + ":" + msg;
    socket->write(msg.toLocal8Bit());
    ui->msgEdit->clear();
}

//断开与服务器连接所对应的自定义槽函数
void Widget::disconnected_slot()
{
    //如果输入框内有内容则清空
    ui->msgEdit->clear();
    //按钮的重新启用与不可用
    ui->msgEdit->setEnabled(false);
    ui->SendBtn->setEnabled(false);
    ui->disconnectBtn->setEnabled(false);
    ui->connectBtn->setEnabled(true);
}

//按下断开连接按钮的槽函数
void Widget::on_disconnectBtn_clicked()
{
    QString msg = username + "退出聊天室";
    socket->write(msg.toLocal8Bit());
    socket->disconnectFromHost();
    connect(socket,&QTcpSocket::disconnected,this,&Widget::disconnected_slot);
}

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

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

相关文章

强化学习-DQN改进及一些强化学习路由优化论文笔记

RL 通用超参数 DQN改进 Duel Structure VS→该state在当前policy下的value QSA→该state进行这个action在当前policy下的value advantage VS - QSA 裁剪区域的确定&#xff1f; 34194按行输出min&#xff0c;33193min为90*90 Replay buffer background knowledge [b…

最优算法100例之41-用两个栈实现队列

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 用两个栈实现队列 题解报告 stack<int> stack1; stack<int> stack2; void push(int node) {stack1.push(node);…

多线程的入门(五)线程池的保活策略

线程池是如何保活的呢&#xff1f;通过对源码的分析得出&#xff0c;线程池通过阻塞队列&#xff0c;与关闭工作线程后新生成空闲线程实现的保活策略源代码如下&#xff1a; runkworker&#xff08;&#xff09;方法的getTask&#xff08;&#xff09;方法中有这样一段代码&…

读书笔记之《如何精心设计提示词来精通ChatGPT》

《如何精心设计提示词来精通ChatGPT》这本书英文标题为&#xff1a;《The Art of Prompt Engineering with chatGPT》&#xff0c;于2023年出版。作者是Nathan Hunter 。 Nathan Hunter简介&#xff1a;ChatGPT培训的创始人。作为一名资深培训师和教学设计师&#xff0c;我在过…

睿尔曼复合机器人之底盘操作流程

以操作流程为例&#xff0c;介绍底盘的操作流程。 开机&#xff1a;长按电源按钮&#xff0c;蜂鸣器短响两声&#xff0c;当第三声变长鸣后松开&#xff0c;等待机器开机。 使用&#xff1a; 建立通讯&#xff1a;主要采用无线WiFi与底盘进行通讯连接 无线连接方式&#xff…

Oracle 数据库 count的优化-避免全表扫描

Oracle 数据库 count的优化-避免全表扫描 select count(*) from t1; 这句话比较简单&#xff0c;但很有玄机&#xff01;对这句话运行的理解&#xff0c;反映了你对数据库的理解深度&#xff01; 建立实验的大表他t1 SQL> conn scott/tiger 已连接。 SQL> drop table …

流媒体的安全谁来保障

流媒体的安全谁来保障 说起媒体&#xff0c;我们马上就会想到报纸新闻、广播、电视。 其实所谓的流媒体同我们通常所指的媒体是不一样的&#xff0c; 它只是一个技术名词。流媒体到底是什么&#xff1f;能给我们的生活带来什么&#xff1f;跟小德一起来看看。 流媒体是什么&a…

最优算法100例之39-机器人的运动范围

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 题目描述: 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,…

备考ICA----Istio实验20---跨网络Primary-Remote主从架构部署

备考ICA----Istio实验20—跨网络Primary-Remote主从架构部署 按照本实验在 cluster1&#xff08;主集群&#xff09;上安装 Istio 控制平面&#xff0c;并将 cluster2&#xff08;远程集群&#xff09;配置为使用 cluster1 中的控制平面。群集 cluster1 在 network1 网络上&am…

[Kubernetes[K8S]集群:master主节点初始化]:通过Calico和Coredns网络插件方式安装

文章目录 操作流程&#xff1a;前置&#xff1a;Docker和K8S安装版本匹配查看0.1&#xff1a;安装指定docker版本 **[1 — 7] ** [ 配置K8S主从集群前置准备操作 ]一&#xff1a;主节点操作 查看主机域名->编辑域名->域名配置二&#xff1a;安装自动填充&#xff0c;虚拟…

贪心算法|763.划分字母区间

力扣题目链接 class Solution { public:vector<int> partitionLabels(string S) {int hash[27] {0}; // i为字符&#xff0c;hash[i]为字符出现的最后位置for (int i 0; i < S.size(); i) { // 统计每一个字符最后出现的位置hash[S[i] - a] i;}vector<int> …

ASUS华硕ROG幻16Air笔记本电脑GU605M原装出厂Win11系统工厂包下载,带有ASUSRecovery一键重置还原

适用型号&#xff1a;GU605MI、GU605MY、GU605MZ、GU605MV、GU605MU 链接&#xff1a;https://pan.baidu.com/s/1YBmZZbTKpIu883jYCS9KfA?pwd9jd4 提取码&#xff1a;9jd4 华硕原厂Windows11系统带有ASUS RECOVERY恢复功能、自带所有驱动、出厂主题壁纸、系统属性联机支持…

VUE typescript 调用stompjs[Rabbit MQ]

npm拉下来最新的2.3.9版本&#xff0c;发现一些原来Js代码已经不能用了。顺便解读了下最新定义的内容 // <reference types"node" />export const VERSIONS: {V1_0: string;V1_1: string;V1_2: string;supportedVersions: () > string[]; };export class C…

风储微网虚拟惯性控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 风储微网虚拟惯性控制系统simulink建模与仿真。风储微网虚拟惯性控制系统是一种模仿传统同步发电机惯性特性的控制策略&#xff0c;它通过集成风力发电系统、储能系统和其他分…

微信小程序自定义关闭按钮在弹窗下面的效果

效果图: 我之前用vant 的popup的弹窗写&#xff0c;会出现close图标移动到弹窗内容外部不可见。 自定义代码&#xff1a; popup.JS/*** 生命周期函数--监听页面初次渲染完成*/onReady() {//自定义弹窗 动态获取屏幕高度var that this;wx.getSystemInfo({success: (result) &…

嵌入式操作教程_数字信号处理_音频编解码:3-6 AAC音频解码实验

一、实验目的 了解AAC音频格式&#xff0c;掌握AAC音频解码的原理&#xff0c;并实现将AAC格式的音频解码为PCM 二、实验原理 音频编解码的主要对象是音乐和语音&#xff0c;音频的编解码格式可分为无压缩的格式、无损压缩格式、有损音乐压缩格式、有损语音压缩格式和合成算…

NotePad++ 快速生成SQL IN (‘’,‘’)

sql In(‘’&#xff0c;‘’)这种形式 第一步&#xff1a;AltC 鼠标放在第一行最左边 第二步 CtrlH $代表行末 第三步 去掉每行换行符 换行可能是"\n" 或者"\r"或者"\r\n" 结果&#xff1a;

TG-12F使用SDK对接阿里生活物联网平台

文章目录 前言一、注意二、准备1. 安装Ubuntu&#xff08;版本20.04 X64&#xff09;程序运行时库。按顺序逐条执行命令&#xff1a;2. 安装Ubuntu&#xff08;版本20.04 X64&#xff09;依赖软件包。按照顺序逐条执行命令&#xff1a;3. 安装Python依赖包。按照顺序逐条执行命…

电子元器件商城开发用什么技术框架?

随着信息技术的飞速发展&#xff0c;电子元器件商城已成为电子工程师和采购人员获取元器件的重要渠道。电子元器件商城的开发涉及众多技术和开发语言的选择&#xff0c;本文将详细分析电子元器件商城开发中常用的技术和开发语言&#xff0c;以及它们各自的优势。 一、电子元器…

数据结构--双向链表

1.双向链表的结构设计 typedef struct DNode { int data; struct DNode* next;//后继指针 struct DNode* prio;//前驱指针 }DNode ,*DList; 2.双向链表的结构示意图: 3.双向链表的实现 //初始化p->prio->next p->next;if (p->next ! NULL)//判断很重要{p->n…