复习 --- QT服务器客户端

news2024/12/23 10:08:45

 

服务器:

头文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTcpServer>
#include<QTcpSocket>
#include<QMessageBox>
#include<QDebug>
#include<QList>
#include<QListWidget>
#include<QLabel>
#include<QLineEdit>
#include<QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;

    //客户端指针
    QTcpSocket *client;
    //存储用户名
    QString uname;

    //聊天框
    QListWidget *text;
    //消息发送框
    QLineEdit *msg;
    //发送按钮
    QPushButton *send;
    //用户名、
    QLabel *userLab;
    //IP
    QLabel *ipLab;
    //PORT
    QLabel *portLab;
    //用户输入框
    QLineEdit *unameEdit;
    //IP输入框
    QLineEdit *ipEdit;
    //端口输入框
    QLineEdit *portEdit;
    //连接服务器按钮
    QPushButton *bconnect;
    //断开服务器按钮
    QPushButton *bdisconnect;

public slots:
    //连接按钮槽函数
    void connectBtn_clicked();
    //声明自定义处理connected信号的槽函数
    void connected_slot();
    //声明自定义处理readyRead信号的槽函数
    void readyRead_slot();
    //声明自定义处理disconnected信号的槽函数
    void disconnected_slot();
    //发送按钮槽函数
    void  sendBtn_clicked();
    //断开连接槽函数
    void disconnectBtn_clicked();
};
#endif // WIDGET_H

widget.cpp文件

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setFixedSize(720,680);

    //聊天框
    text = new QListWidget(this);
    text->setFixedSize(720,400);
    //消息发送框
    msg = new QLineEdit(this);
    msg->resize(500,50);
    msg->move(10,420);
    //发送按钮
    send = new QPushButton(this);
    send->setText("发送");
    send->resize(150,50);
    send->move(520,420);
    //用户名
    userLab = new QLabel(this);
    userLab->setText("用户名:");
    userLab->setAlignment(Qt::AlignCenter);
    userLab->resize(100,30);
    userLab->move(30,500);
    //IP
    ipLab = new QLabel(this);
    ipLab->setText("IP:");
    ipLab->setAlignment(Qt::AlignCenter);
    ipLab->resize(100,30);
    ipLab->move(30,550);
    //PORT
    portLab = new QLabel(this);
    portLab->setText("Port:");
    portLab->setAlignment(Qt::AlignCenter);
    portLab->resize(100,30);
    portLab->move(30,600);
    //用户输入框
    unameEdit = new QLineEdit(this);
    unameEdit->resize(300,30);
    unameEdit->move(140,500);
    //IP输入框
    ipEdit = new QLineEdit(this);
    ipEdit->resize(300,30);
    ipEdit->move(140,550);
    //端口输入框
    portEdit = new QLineEdit(this);
    portEdit->resize(300,30);
    portEdit->move(140,600);
    //连接服务器按钮
    bconnect = new QPushButton(this);
    bconnect->resize(120,50);
    bconnect->setText("连接");
    bconnect->move(520,500);
    //断开服务器按钮
    bdisconnect = new QPushButton(this);
    bdisconnect->resize(120,50);
    bdisconnect->setText("断开连接");
    bdisconnect->move(520,580);

    client = new QTcpSocket(this);
    //连接按钮信号
    connect(bconnect,&QPushButton::clicked,this,&Widget::connectBtn_clicked);
    //连接上后客户端自动发送一个connected信号,只需要连接一次
    connect(client,&QTcpSocket::connected,this,&Widget::connected_slot);
    //如果服务器有数据发送给该客户端,那么该套接字就会自动发射一个readyRead信号
    connect(client, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
    //发送按钮
    connect(send,&QPushButton::clicked,this,&Widget::sendBtn_clicked);
    //当成功与服务器断开连接后,该客户端就会自动发射一个disconnected的信号
    connect(client, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);
}

Widget::~Widget()
{
    delete ui;

}

//连接按钮槽函数
void Widget::connectBtn_clicked()
{
    //获取ip和端口
    QString ip = ipEdit->text();
    quint16 port = portEdit->text().toUInt();

    //连接主机
    client->connectToHost(ip,port);
}
//声明自定义处理connected信号的槽函数
void Widget::connected_slot()
{
    QMessageBox::information(this,"","连接服务器成功");

    uname = unameEdit->text();
    QString msgs = uname+":进入聊天室";

    client->write(msgs.toLocal8Bit());

    msg->setEnabled(true);
    send->setEnabled(true);
    bdisconnect->setEnabled(true);
    unameEdit->setEnabled(false);
    ipEdit->setEnabled(false);
    portEdit->setEnabled(false);
    bconnect->setEnabled(false);

}
//声明自定义处理readyRead信号的槽函数
void Widget::readyRead_slot()
{
    //接收到服务器消息后
    QByteArray msgbox = client->readAll();
    //显示
    text->addItem(QString::fromLocal8Bit(msgbox));
}
//声明自定义处理disconnected信号的槽函数
void Widget::disconnected_slot()
{
    QString msgbox = uname+":离开聊天室";
    client->write(msgbox.toLocal8Bit());
    //断开后客户端会发送一个disconnected信号
    client->disconnectFromHost();
}
//发送按钮槽函数
void Widget::sendBtn_clicked()
{
    QString msgbox = msg->text();
    msgbox = uname+":"+msgbox;
    //发送
    client->write(msgbox.toLocal8Bit());
    msg->clear();

}
//断开连接槽函数
void Widget::disconnectBtn_clicked()
{
    QMessageBox::information(this,"","成功断开");
    msg->setEnabled(false);
    send->setEnabled(false);
    bdisconnect->setEnabled(false);
    unameEdit->setEnabled(true);
    ipEdit->setEnabled(true);
    portEdit->setEnabled(true);
    bconnect->setEnabled(true);
}

 

客户端

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTcpServer>
#include<QTcpSocket>
#include<QMessageBox>
#include<QDebug>
#include<QList>
#include<QListWidget>
#include<QLabel>
#include<QLineEdit>
#include<QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
    //定义服务器指针
    QTcpServer *server;
    //定义客户端容器
    QList<QTcpSocket*> socketList;

    //对话框
    QListWidget *text;
    //端口号
    QLabel * l_port;
    //端口输入框
    QLineEdit *edit_port;
    //启动按钮
    QPushButton *bstart;

private slots:
    //按键槽函数
    void start_clicked();
    //连接槽函数
    void newConnection_slot();
    //readyRead信号处理槽函数
    void readyRead_slot();

};
#endif // WIDGET_H

widget.cpp

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

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

    this->setFixedSize(680,500);

    //对话框
    text = new QListWidget(this);
    text->setFixedSize(680,350);
    //端口号
    l_port = new QLabel(this);
    l_port->setText("端口号:");
    l_port->resize(50,30);
    l_port->move(50,400);

    //端口输入框
    edit_port = new QLineEdit(this);
    edit_port->resize(380,30);
    edit_port->move(120,400);
    //启动按钮
    bstart = new QPushButton(this);
    bstart->setText("启动服务器");
    bstart->resize(100,30);
    bstart->move(520,400);

    server = new QTcpServer(this);

    connect(bstart,&QPushButton::clicked,this,&Widget::start_clicked);
}

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

void Widget::start_clicked()
{
    qDebug()<<"ok";  //测试
    //判断输入框中是否有内容
    if(edit_port->text() == NULL)
    {
        QMessageBox::information(this,"错误","端口号为空!");
    }
    else
    {
        //获取输入框中的内容
        quint16 port = edit_port->text().toUInt();
        qDebug()<<port;
        QString ip = "192.168.1.2";
        QHostAddress address(ip);

        //将服务器设置成监听状态,监听客户段发来的连接请求
        if(server->listen(QHostAddress::Any,port))
        {
            QMessageBox::information(this,"","服务器启动成功");
        }
        else
        {
            QMessageBox::information(this,"","服务器启动失败");
        }

        //此时服务器已经进入监听状态,客户段发来连接请求,服务器就会自动发射一个newConnext信号
        connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);
    }
}

void Widget::newConnection_slot()
{
    qDebug()<<"有客户连接";
    //获取最新连接的客户段套接字
    QTcpSocket *client = server->nextPendingConnection();
    //将套接字放入客户端容器
    socketList.push_back(client);

    //监听套接字,有数据则客户端会发送一个readyRead信号
    connect(client,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
}

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++)
    {
        //获取套接字是否有有效数据
        if(socketList.at(i)->bytesAvailable() != 0)
        {
            //获取套接字内信息
            QByteArray msg = socketList.at(i)->readAll();
            text->addItem(QString::fromLocal8Bit(msg));
            for (int j = 0;j<socketList.count();j++)
            {
                socketList.at(j)->write(msg);

            }
        }
    }
}

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

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

相关文章

电脑数据恢复怎么操作?电脑数据恢复难点是什么

随着电脑在我们日常生活中的普及&#xff0c;数据的重要性不言而喻。然而&#xff0c;在某些情况下&#xff0c;我们可能会不小心删除或因其他原因导致丢失了重要的电脑数据&#xff0c;这时候就需要进行数据恢复操作。下面我们一起来了解下电脑数据恢复的操作方法&#xff0c;…

【全3D打印坦克——基于Arduino履带式机器人】

【全3D打印坦克——基于Arduino履带式机器人】 1. 概述2. 设计机器人平台3. 3D 模型和 STL 下载文件3.1 3D打印3.2 组装 3D 打印坦克 – 履带式机器人平台3.3 零件清单 4. 机器人平台电路图4.1 定制电路板设计4.2 完成 3D 打印储罐组件 5. 机器人平台编程6. 测试3D打印机器人 -…

侯捷 C++ STL标准库和泛型编程【C++学习笔记】 超详细 万字笔记总结 笔记合集

关于STL这部分&#xff0c;原课程将其分为了四部分&#xff0c;我做笔记时&#xff0c;会将其整合&#xff0c;使其更具有整体性 文章目录 1 STL概述1.1 头文件名称1.2 STL基础介绍1.3 typename 2 OOP vs. GP3 容器3.1 容器结构分类3.2 序列式容器3.2.1 array测试深度探索 3.2.…

Python3操作MongoDb7最新版创建文档及CRUD基本操作

Python3中类的高级语法及实战 Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案 Python3数据科学包系列(一):数据分析实战 Python3数据科学包系列(二):数据分析实战 Python3数据科学包系列(三):数据分析实战 MongoDB 操作手册----文档…

Zookeeper经典应用场景实战(一)

文章目录 1、Zookeeper Java客户端实战1.1、 Zookeeper 原生Java客户端使用1.2、 Curator开源客户端使用 2、 Zookeeper在分布式命名服务中的实战2.1、 分布式API目录2.2、 分布式节点的命名2.3、 分布式的ID生成器 3、Zookeeper实现分布式队列3.1、 设计思路3.2、 使用Apache …

电脑桌面黑屏,但程序还可以正常运行

问题&#xff1a;桌面黑屏&#xff0c;程序可以正常运行操作 解决方法: 1.Ctrl Alt Del 2.点击 【任务管理器】-->【文件F】-->【运行新任务N】 3.输入 explorer.exe 回车

Docker 镜像的缓存特性

Author&#xff1a;rab 目录 前言一、构建缓存二、Pull 缓存总结 前言 首先我们要清楚&#xff0c;Docker 的镜像结构是分层的&#xff0c;镜像本身是只读的&#xff08;不管任何一层&#xff09;&#xff0c;当我们基于某镜像运行一个容器时&#xff0c;会有一个新的可写层被…

Spring的AOP开发-注解方式开发AOP

基于注解配置的AOP 注解方式AOP的基本使用 Spring的AOP也提供了注解方式配置&#xff0c;使用相应的注解替代之前的xml配置&#xff0c;xml配置AOP时&#xff0c;我们主要配置了三部分&#xff1a;目标类被Spring容器管理&#xff08;注解使用Service&#xff09;、通知类被S…

图像和视频上传平台Share Me

本文完成于 6 月&#xff0c;所以反代中&#xff0c;域名演示还是使用的 laosu.ml&#xff0c;不过版本并没有什么变化&#xff1b; 什么是 Share Me &#xff1f; Share Me 是使用 Next.js 和 PocketBase 的自托管图像和视频上传平台&#xff0c;具有丰富的嵌入支持和 API&…

基于Java的高校宿舍管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

【C++】unordered_map和unordered_set

哈希表 1. unordered_map1.1 概念1.2 常见接口 2. unordered_set2.1 概念2.1 常见接口 3. 底层实现3.1 哈希3.2 哈希函数3.3 闭散列和开散列3.3.1 闭散列3.3.2 开散列 3.4 模拟实现3.4.1 改造哈希桶3.4.2 模拟实现unordered_set3.4.3 模拟实现unordered_map 在C11中&#xff0c…

Promise, async, await 学习

异步编程简介&#xff1a; 介绍&#xff1a;异步编程是一种编程范式&#xff0c;旨在提高程序的性能和响应能力。该模型允许程序在执行某些任务时&#xff0c;不必等待这些任务完成就可以进行下一步操作&#xff0c;从而提高了程序的效率。 作用&#xff1a;异步编程通常用于…

IPT2602协议-USB 快速充电端口控制器

产品描述&#xff1a; IPT2602是一款USB端口快速充电协议控制芯片。IPT2602智能识别多种快速充电协议&#xff0c;对手机等受电设备进行快速充电。IPT2602根据受电设备发送的电压请求能够精确的调整VBUS输出电压&#xff0c;从而实现快速充电。 IPT2602在调整5V输出电压前会自动…

10.5 认识XEDParse汇编引擎

XEDParse 是一款开源的x86指令编码库&#xff0c;该库用于将MASM语法的汇编指令级转换为对等的机器码&#xff0c;并以XED格式输出&#xff0c;目前该库支持x86、x64平台下的汇编编码&#xff0c;XEDParse的特点是高效、准确、易于使用&#xff0c;它可以良好地处理各种类型的指…

[硬件基础]-快速了解RS232串行通信

快速了解RS232串行通信 文章目录 快速了解RS232串行通信1、概述2、什么是串行数据通信&#xff1f;3、什么是RS232&#xff1f;4、RS232应用5、RS232如何工作&#xff1f;6、RS232协议基础6.1 电压与逻辑表示6.2 数据编码6.3 起始位和停止位6.4 奇偶校验位6.5 波特率6.5 RS232电…

掌握 SwiftUI 中的 ScrollView

文章目录 前言scrollTransition 修饰符ScrollTransitionPhase弹性动画总结 前言 SwiftUI 框架的第五个版本引入了许多与 ScrollView 相关的新 API&#xff0c;使其比以前更强大。本周将开始介绍 ScrollView 在 SwiftUI 中的新功能系列文章&#xff0c;首先我们将讨论滚动过渡。…

【LeetCode: 918. 环形子数组的最大和 | 动态规划】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

关联规则挖掘(上):数据分析 | 数据挖掘 | 十大算法之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

【全方位带你配置yolo开发环境】快速上手yolov5

本文用于记录yolo开发环境的配置&#xff0c;以及我在配置中出现的各种问题&#xff0c;以供大伙参考。&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; 本人持续分享更多关于电子通信专业内容以及嵌入式和单片机的知识…

阿里云服务器ECS详细介绍_云主机_服务器托管_弹性计算

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云服务器网分享阿…