QTday5作业

news2024/12/24 3:26:43

Tcp服务器

源文件

#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_btn_clicked()
{
    //获取ui界面上的端口号
    quint16 port = ui->lineEdit->text().toUInt();
    //将服务器设置成监听状态
    //bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
    //参数1:要监听的主机地址,any表示监听所有主机地址,也可以给定特定主机地址
    //2:通过指定的端口号进行访问服务器,若是0,表示由服务器自动分配
    //返回值:成功返回真。失败返回假
    if(!server->listen(QHostAddress::Any,port))
    {
        QMessageBox::critical(this,"失败","服务器启动失败");
        return;
    }else
    {
         QMessageBox::information(this,"成功","服务器启动成功");
    }
    //此时表明服务器启动成功,并对服务器连接进行监听
    //如果有客户端向服务器发来连接请求
    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::readRead_slot);

}

//关于readyRead信号对应的槽函数的实现
void Widget::readRead_slot()
{
    //删除客户端链表中的无效客户端套接字
    for(int i=0;i<clientList.count();i++)
    {
        //判断套接字状态
        //SocketState state() const;
        //功能:返回客户端套接字状态
        //返回值:客户端状态,0表示未连接
        if(clientList[i]->state() == 0)
        {
            //将下表为i的客户端移除掉
            clientList.removeAt(i);
        }
    }
    //遍历所有客户端,查看是哪个客户端发来的数据
    for(int i = 0; i<clientList.count(); i++)
    {
        // qint64 bytesAvailable() const override;
        //返回当前客户端套接字中刻度数据字节个数
        //==0表示无数据
        if(clientList[i]->bytesAvailable() !=0)
        {
            //读取当前客户端相关的数据
            //获取所有数据,并返回一个字节数组
            QByteArray msg = clientList[i]->readAll();
            //将数据展示到ui界面上
            ui->listWidget->addItem(QString::fromLocal8Bit(msg));

            //将接收到的信息,发送给所有客户端
            for(int j=0; j<clientList.count(); j++)
            {
                clientList[j]->write(msg);
            }
        }
    }
}

头文件

#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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_btn_clicked();

    void newConnection_slot();//自定义处理newConnection_slot槽函数

    void readRead_slot();//

private:
    Ui::Widget *ui;

    //定义服务器指针
    QTcpServer *server;
    //客户端指针链表容器
    QList<QTcpSocket *> clientList;
};
#endif // WIDGET_H

Tcp客户端

源文件

#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_btn2_clicked()
{
    //获取ui界面的信息
    userName = ui->lineEdit_2->text(); //  获取用户名
    QString hostName = ui->lineEdit_3->text();//获取主机地址
    quint16 port = ui->lineEdit_4->text().toUInt();//获取端口号
    //
    //调用函数连接到主机connectToHost
    //参数1:服务器的主机地址
    //参数2:端口号
    //
    socket->connectToHost(hostName,port);

    //
}

//处理connected信号的槽函数
void Widget::connected_slot()
{
    //
    QMessageBox::information(this,"成功","连接服务器成功");
    //向服务器发送信息
    QString msg = userName + ":进入聊天室";
    //
    socket->write(msg.toLocal8Bit());
}

//readRead信号对应的槽函数的实现
void Widget::readyRead_slot()
{
    //读取该客户端中的数据
    QByteArray msg = socket->readAll();

    //将数据展示在ui界面
    ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}

//发送按钮
void Widget::on_btn1_clicked()
{
    //获取Ui界面上的编辑文本内容
    QString m = ui->lineEdit->text();
    //整合发送的信息
    QString msg = userName + ": " + m;
    //将信息发送给服务器
    socket->write(msg.toLocal8Bit());

    //将信息编辑框中内容清空
    ui->lineEdit->clear();
}

//断开服务器按钮对应的槽函数
void Widget::on_btn3_clicked()
{
    //准备要发送的信息
    QString msg = userName +":离开聊天室";
    socket->write(msg.toLocal8Bit());

    //断开客户端与服务器连接
    socket->disconnectFromHost();

    //
}

//disconnected_slot信号对应的槽函数
void Widget::disconnected_slot()
{
    //
    QMessageBox::information(this,"退出","断开成功");
}

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>  //客户端头文件
#include <QMessageBox>  //
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_btn2_clicked();
    void connected_slot();  //自定义处理connected信号的槽函数
    void readyRead_slot();   //处理readyRead信号的槽函数
    void on_btn1_clicked();

    void on_btn3_clicked();
    void disconnected_slot();    //自定义disconnected_slot信号的槽函数

private:
    Ui::Widget *ui;

    //定义一个客户端指针
    QTcpSocket *socket;

    //
    QString userName;   //用户名
};
#endif // WIDGET_H

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

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

相关文章

Android数据结构和算法总结-字符串相关高频面试题算法

前言 周末闲来无事&#xff0c;在七月在线上看了看字符串相关算法的讲解视频&#xff0c;收货颇丰&#xff0c;跟着视频讲解简单做了一下笔记&#xff0c;方便以后翻阅复习同时也很乐意分享给大家。什么字符串在算法中有多重要之类的大路边上的客套话就不多说了&#xff0c;直…

linux删除了业务进程正在使用的文件,又不能停止进程,如何释放文件占用的磁盘空间

一台linux分区使用率告警&#xff0c;同事为了清理空间&#xff0c;通过du -sh *查到应用的日志文件占用很高&#xff0c;他直接rm删除了日志文件。但df -h看分区空间并没有释放。 执行lsof | grep delete可以看到刚刚删除的文件因为被正在运行的进程调用所以并没有释放磁盘空间…

优维产品最佳实践:如何设计流水线?

前言&#xff1a;我们上期介绍了什么是CI以及CI的重要性&#xff0c;本期目标就是学习如何设计流水线&#xff0c;流水线是一种用于自动化软件开发和部署的工具链&#xff0c;它可以将软件开发过程中的各个步骤组织成一个连续的流程&#xff0c;从而提高开发效率和软件质量。在…

安装虚拟机+安装/删除镜像

安装虚拟机 注意&#xff0c;官网可能无法登录&#xff0c;导致无法从官网下载&#xff0c;就自己去网上搜靠谱的下载&#xff0c;我用的16.2.3 删除镜像 Vm虚拟机怎么删除已经创建的系统&#xff1f;Vm虚拟机创建好之后iso删除方法 - 系统之家 (xitongzhijia.net) 安装镜像…

Python中内建模块和标准库的工作原理? - 易智编译EaseEditing

Python中的内建模块和标准库是Python编程语言的一部分&#xff0c;它们提供了大量的功能和工具&#xff0c;可用于各种任务和应用程序。这些模块和库通常是由Python官方维护的&#xff0c;因此在任何标准Python安装中都是可用的。 以下是内建模块和标准库的工作原理的概述&…

数据结构——单调队列

单调队列 单调队列的概念和操作过程 概念&#xff1a; 单调队列和单调栈在操作上有相似之处&#xff0c;但因为单调队列是队列&#xff0c;所以多了一项特殊操作&#xff0c;即头部的元素可以出队&#xff0c;相当于滑动窗口向后滑动。这头部的出队操作就相当于淘汰&#xff0c…

需求管理做不好,项目成功难保障

你是否曾感觉客户的要求总是突然冒出来&#xff1f;或是觉得自己跟不上订单的节奏&#xff1f;不了解产品的需求会让你手忙脚乱&#xff0c;如果没有足够的资源来应对&#xff0c;甚至会损害你的业务。 本文将向你介绍需求管理的流程&#xff0c;以及如何在业务中使用它。 项目…

【洛谷算法题】P5703-苹果采购【入门1顺序结构】

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5703-苹果采购【入门1顺序结构】&#x1f30f;题目描述&#x1f30f;输入格式&a…

BCSP-玄子Share-Java框基础_反射

一、反射 1.1 反射介绍 Java反射&#xff1a;在编译时不确定哪个类被加载&#xff0c;而在程序运行时才加载、探知、使用 1.1.1 Java 程序的运行过程 1.1.2 反射及其作用 反射是指能够在运行时&#xff0c;观察并修改自己运行时(Runtime)行为的特性 Java 反射机制主要提供了…

verilog语法之case casez casex

在rtl仿真中&#xff0c;有四种状态&#xff0c;分别是0、1、x&#xff08;unknown values&#xff09;和z&#xff08;high-impedance values&#xff09;。 case 结构体中&#xff1a;0&#xff0c;1&#xff0c;X与Z是四种不同的状态&#xff0c;case条件比较时会检测比较双…

2023年03月 C/C++(七级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;走出迷宫 当你站在一个迷宫里的时候&#xff0c;往往会被错综复杂的道路弄得失去方向感&#xff0c;如果你能得到迷宫地图&#xff0c;事情就会变得非常简单。 假设你已经得到了一个n*m的迷宫的图纸&a…

BCSP-玄子Share-Java框基础_工厂模式/代理模式

三、设计模式 3.1 设计模式简介 软件设计中的三十六计是人们在长期的软件开发中的经验总结是对某些特定问题的经过实践检验的特定解决方法被广泛运用在 Java 框架技术中 3.1.1 设计模式的优点 设计模式是可复用的面向对象软件的基础可以更加简单方便地复用成功的设计和体系…

【管理运筹学】第 7 章 | 图与网络分析(2,最小支撑树问题)

文章目录 引言二、最小支撑树问题2.1 树的定义及其基本性质2.2 图的支撑树2.3 最小支撑树的定义及有关定理2.4 最小支撑树算法2.4.1 避圈法&#xff08;KRUSKAL算法&#xff09;2.4.2 反圈法&#xff08;PRIM算法&#xff09;2.4.3 破圈法 写在最后 引言 承接前文&#xff0c;…

宠物电商Chewy第二季度销售额28亿美元,同比增长14.3%

美国宠物电商Chewy公布2023年第二季度财报。报告显示&#xff0c;其Q2季度销售额同比增长14.3%至28亿美元&#xff0c;超出市场预期。 以下为Chewy期内业绩概要&#xff1a; 1.毛利率28.3%&#xff0c;同比增长20个基点 2.净利润有所收窄&#xff0c;同比下降15.2%至1890万美…

QT连接数据库

目录 数据库 数据库基本概念 常用的数据库 SQLite3基础 SQLite特性&#xff1a; QT连接数据库 1.1 QT将数据库分为三个层次 1.2 实现数据库操作的相关方法 sql语句&#xff08;常用&#xff09; 1&#xff09;创建表格 2&#xff09;删除表格 3&#xff09;插入记录 …

应急物资管理系统DW-S300|助力应急物资保障体系建设

国务院新闻办公室于2023年7月25日举行国务院政策例行吹风会&#xff0c;介绍防汛抗旱工作情况&#xff0c;并答记者问。应急管理部副部长、水利部副部长王道席介绍&#xff0c;要推进应急物资保障体系建设。去年&#xff0c;应急管理部会同国家发展改革委、财政部、国家粮食和物…

AIGC专栏5——EasyPhoto AI写真照片生成器 sd-webui插件介绍、安装与使用

AIGC专栏5——EasyPhoto AI写真照片生成器 插件安装与使用 学习前言源码下载地址技术原理储备&#xff08;SD/Control/Lora&#xff09;StableDiffusionControlNetLora EasyPhoto插件简介EasyPhoto插件安装安装方式一&#xff1a;Webui界面安装 &#xff08;需要良好的网络&…

Linux监测进程打开文件

分析问题过程中&#xff0c;追踪进程打开的文件可以在许多不同情况下有用&#xff0c;体现在以下几个方面&#xff1a; 故障排除和调试&#xff1a; 当程序出现问题、崩溃或异常行为时&#xff0c;追踪进程打开的文件可以帮助找出问题的根本原因。这有助于快速定位错误&#x…

深入解析 curl:掌握命令行的网络传输利器

当我们使用 curl 进行网络请求时&#xff0c;了解如何有效地使用参数是非常重要的。curl 提供了许多参数&#xff0c;用于控制请求的行为和配置。在这篇博客文章中&#xff0c;我们将详细解释一些常用的 curl 参数&#xff0c;帮助你更好地理解如何利用这个强大的工具。 什么是…

兵者多诡(HCTF2016)

环境:https://github.com/MartinxMax/CTFer_Zero_one 题目简介 解题过程 登录首页 提交png图片上传抓包&#xff0c;可以看到是向upload文件提交数据 在fp参数中尝试伪协议读取home.php文件 http://127.0.0.1:88/HCTF2016-LFI/home.php?fpphp://filter/readconvert.base64…