Qt creator day5练习

news2025/3/12 11:04:01

Qt 中实现TCP 聊天服务器

大致流程

创建套接字服务器QTcpServer对象

通过QTcpServer对象设置监听,即QTcpServer::listen()

基于QTcpServer::newConnection()信号检测是否有新的客户端连接

如果有新的客户端连接 调用QTcpSocket *QTcpServer::nextPendingConnection()得到通信的套接字对象

使用通信的套接字对象QTcpSocket和客户端进行通信

.pro文件

QT       += core gui network    # 所需模块network 添加后记得构建

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

.h文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>  //??包含TCP服务器类
#include <QMessageBox> //消息对话框类
#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_startBtn_clicked();
    void newConnection_slot();  //声明一下服务器检测到新的客户端连接时,发射出来的信号到这个槽函数
    void readyRead_slot();  //声明一下客户端发射的readyRead()信号对应的槽函数

private:
    Ui::Widget *ui;

    QTcpServer *server; //创建一个套接字服务器QTcpServer对象 在构造函数初始化列表中初始化

    QList<QTcpSocket *> socketList;  //定义一个存放客户套接字的容器
};
#endif // WIDGET_H

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

.cpp文件

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    ,server(new QTcpServer(this))  //初始化列表 初始化server
{
    ui->setupUi(this);

}

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


void Widget::on_startBtn_clicked()
{
    //定义一个 quint16 类型的变量port 接收 字符串端口转换成 整型的端口
    quint16 port = ui->portEdit->text().toUInt();

    //调用 QTcpServer类型的对象server里的listen函数,实现监听
    if(server->listen(QHostAddress::Any,port))
    {
        //启动监听成功
        QMessageBox::information(this,"","启动服务器成功");
    }
    else
    {
        //启动监听失败
        QMessageBox::critical(this,"","启动服务器失败");
    }

    //此时服务器已经成功启动监听,如果有客户端发来连接,那么服务器端就会自动发射一个newConnection()的信号
    //将该信号连接到自定义的槽函数中
    connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);

}

//newConnection_slot()槽函数的实现
//有客户端连接时,服务器发射一个newConnection信号后,执行这个函数
void Widget::newConnection_slot()
{
    //使用QTcpSocket *QTcpServer::nextPenddingConnection()函数得到通信的套接字对象
    QTcpSocket *s = server->nextPendingConnection();
    socketList.push_back(s);  // 用尾插法将套接字放入链表
    //如果有客户端发来数据,客户端就会自动发射一个readyRead信号,就可以将该信号连接到自定义的槽函数中
    connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);

}

//客户端发射信号对应的槽函数的实现
void Widget::readyRead_slot()
{
    //遍历有效客户端,移除无效客户端
    for(int i=0; i<socketList.count(); i++)
    {
        if(socketList.at(i)->state() == 0)
        {
            socketList.removeAt(i); //删除该元素
        }
    }

    //再遍历客户端容器,寻找哪个客户端的数据待读
    for(int i=0; i<socketList.count(); i++)
    {
        if(socketList.at(i)->bytesAvailable() != 0)
        {
            //!= 0 说明这些是有效数据
            QByteArray msg = socketList.at(i)->readAll();
            //将读取到的数据 放到ui界面上
            ui->listWidget->addItem(QString::fromLocal8Bit(msg));  //fromlocal8bit() 将Windows的GBK字符转换为Qt的Unicode
                                                                   //QString::Local8bit是本地操作系统设置的字符集编码
            //将数据广播给所有客户端
            for(int i=0; i<socketList.count(); i++)
            {
                socketList.at(i)->write(msg);
            }
        }
    }

}


























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

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

相关文章

大模型面试题目精选分享

前言 掌握大模型面试关键&#xff0c;我精选了一系列面试题目。从模型理解到应用实践&#xff0c;全方位考察大模型知识。无论你是初学者还是资深专家&#xff0c;这里都有适合你的题目。快来挑战自己&#xff0c;提升面试技能吧&#xff01; 面试题笔记分享 为了助力朋友们…

日常工作中常用的管理工具

日常工作中常用的管理工具 SWOT分析法&#xff1a; 帮你清晰地把我全局&#xff0c;分析自己在资源方面的优势域劣势&#xff0c;把握环境提供的机会&#xff0c;防范可能存在的风险与威胁&#xff0c;对我们的成功有非常重要的意义 PDCA循环规则&#xff1a; 每一项工作&#…

RPM 打包入门(基于openEuler)

主要参考内容&#xff08;均为官方文档&#xff09;&#xff1a; https://rpm-packaging-guide.github.io/#building-rpms https://docs.redhat.com/zh_hans/documentation/red_hat_enterprise_linux/8/html/packaging_and_distributing_software/introduction-to-rpm_packagin…

用Python设置Excel工作表网格线的隐藏与显示

Excel表格界面的直观性很大程度上得益于表格中的网格线设计&#xff0c;这些线条帮助用户精确对齐数据&#xff0c;清晰划分单元格。网格线是Excel界面中默认显示的辅助线&#xff0c;用于辅助定位&#xff0c;与单元格边框不痛&#xff0c;不影响打印输出。然而&#xff0c;在…

Spring的启动扩展点机制详解

在Java的世界中&#xff0c;我们知道Spring是当下最主流的开发框架&#xff0c;没有之一。而在使用Dubbo、Mybatis等开源框架时&#xff0c;我们发现可以采用和Spring完全一样的使用方式来使用它们。 可能你在平时的使用过程中并没有意识到这一点&#xff0c;但仔细想一想&…

34 张动图:线缆,以太网与网络寻址

以太网 本地主机访服务器 以太网标准 非屏蔽双绞线&#xff08;UTP&#xff09; 电磁干扰 串扰 双绞线 真实的双绞线 线缆与引脚对齐方式 科普&#xff1a;网线每根芯的作用 引脚连接 数据传输与接收 主机直连到交换机 主机直连到主机&#xff08;或交换器&#xff09; Auto M…

C++ 矩阵的最小路径和解法

描述 给定一个 n * m 的矩阵 a&#xff0c;从左上角开始每次只能向右或者向下走&#xff0c;最后到达右下角的位置&#xff0c;路径上所有的数字累加起来就是路径和&#xff0c;输出所有的路径中最小的路径和。 数据范围: 1≤&#x1d45b;,&#x1d45a;≤5001≤n,m≤500&…

# 消息中间件 RocketMQ 高级功能和源码分析(九)

消息中间件 RocketMQ 高级功能和源码分析&#xff08;九&#xff09; 一、消息中间件 RocketMQ 源码分析&#xff1a; 同步刷盘分析 1、刷盘机制 RocketMQ 的存储是基于 JDK NIO 的内存映射机制&#xff08;MappedByteBuffer&#xff09;的&#xff0c;消息存储首先将消息追…

好用的便签是什么 电脑桌面上好用的便签

作为一名文字工作者&#xff0c;我经常需要在繁杂的思绪中捕捉灵感&#xff0c;记录下那些一闪而过的想法。在寻找一款适合电脑桌面的便签应用时&#xff0c;我偶然发现了敬业签便签软件简直是为我量身定制的&#xff0c;它不仅界面简洁&#xff0c;操作便捷&#xff0c;更重要…

前瞻展望,中国信通院即将发布“2024云计算十大关键词”

人类对于未知领域的探索欲望&#xff0c;似乎总是无穷无尽&#xff0c;而探索欲反过来推动了技术的革新与进步。今年以来&#xff0c;AI大模型成为科技领域最为确定的趋势之一。在大模型开启的AI原生时代&#xff0c;AI原生正在重构云计算的演化逻辑和发展走向&#xff0c;MaaS…

含铬废水有哪些危害?含铬废水怎么处理呢?

铬化物可以通过消化道、呼吸道、皮肤和粘膜侵人人体&#xff0c;主要积聚在肝、肾、内分泌系统和肺部。毒理作用是影响体内物质氧化、还原和水解过程&#xff0c;与核酸、核蛋白结合影响组织中的磷含量。铬化合物具有致癌作用。 铬化合物以蒸汽和粉尘的方式进入人体组织中&…

gstreamer+qt5实现简易视频播放器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、安装环境1.QT52.gstreamer 二、代码1.Windows实现 三、测试效果总结 前言 最近在研究mpp&#xff0c;通过gstreamer实现了硬解码&#xff0c;但是我在想我…

ip地址怎么写才是的对的?合法ip地址正确的格式

IP地址怎么写才是的对的&#xff1f;在互联网的世界里&#xff0c;IP地址就像是我们生活中的门牌号码&#xff0c;它是每个设备在网络中的唯一标识。正确的书写IP地址对于确保网络通信的顺畅至关重要。本文将带您了解合法IP地址的正确格式与书写规范&#xff0c;并深入探讨其在…

【MySQL】索引的原理及其使用

文章目录 什么叫索引减少磁盘IO次数缓存池(Buffer Pool&#xff09;MySQL的页页内目录页目录 正确理解索引结构为什么Innodb的索引是B树结构各种存储引擎支持的索引聚簇索引和非聚簇索引索引类型 关于索引的操作创建主键索引唯一索引的创建普通索引的创建查看索引删除索引 什么…

6月21日(周五)AH股总结:沪指失守3000点,恒生科技指数跌近2%,多只沪深300ETF午后量能显著放大

内容提要 沪指全天围绕3000点关口来回拉锯&#xff0c;收盘跌破3000点。白酒及光刻机概念集体走低&#xff0c;中芯国际港股跌超2%。CRO医药概念及水利股逆势走强。 A股低开低走 沪指全天围绕3000点关口来回拉锯&#xff0c;收盘跌破3000点&#xff0c;跌0.24%。深成指跌0.04…

如何在 MySQL 中创建和使用事务?

目录 1. 环境准备 2. 创建事务 3. 事务执行 4. 事务撤消 5. 总结 事务是数据库区别于文件系统的重要特征之一&#xff0c;当我们有了事务就会让数据库始终保持一致&#xff0c;同时我们还能通过事务机制恢复到某个时间点&#xff0c;这样可以保证已提交到数据库的修改不会…

【Linux】基础IO_2

文章目录 六、基础I/O2. 系统文件I/O磁盘的存储结构 未完待续 六、基础I/O 2. 系统文件I/O 磁盘的存储结构 系统中不是所有对文件都是打开的状态&#xff0c;大部分的文件都是没有被打开的。这些文件一般都被存储在磁盘当中。磁盘通过柱面&#xff0c;扇面&#xff0c;扇区确…

JS 【详解】树的遍历(含深度优先遍历和广度优先遍历的算法实现)

用 js 描述树 let tree [{label:a,children:[{label:b,children:[{label:d},{label:e}]},{label:c,children:[{label:f}]}]} ]使用数组是因为树的节点有顺序 深度优先遍历 从根节点出发&#xff0c;优先遍历最深的节点 遍历顺序为 abdecf function DFS(tree) {tree.forEach(…

c++编译器优化不显示拷贝构造函数

一.错误情景&#xff08;无法打印拷贝函数&#xff09; #include<iostream> using namespace std;class person { public:person(){cout << "person默认构造函数调用" << endl;}person(int age){cout << "有参构造函数调用" <…

IIS代理配置-反向代理

前后端分离项目&#xff0c;前端在开发中使用proxy代理解决跨域问题&#xff0c;打包之后无效。 未配置前无法访问 部署环境为windows IIS&#xff0c;要在iis设置反向代理 安装代理模块 需要在iis中实现代理&#xff0c;需要安装Application Request Routing Cache和URL重…