QT/基于TCP的服务端实现

代码

widget.cpp

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    ,p(new QTcpServer(this))//给服务器指针申请空间
{
    ui->setupUi(this);
}

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


void Widget::on_pushButton_clicked()//启动服务器按钮对应槽函数
{
    //获取ui界面的端口号
    quint16 port=ui->lineEdit->text().toUInt();//将获取的行编辑器的字符转为无符号整型
    //设置服务器监听
    if(p->listen(QHostAddress::Any,port)){
        QMessageBox::information(this,"提示","服务器启动成功");
    }else{
        QMessageBox::information(this,"提示","服务器启动失败");
        return;
    }
    //此时服务器已建立监听,如客户端发来连接,服务器自动发送一个newConnection()信号
    //将该信号连接到自定义的槽函数中,处理逻辑
    connect(p,&QTcpServer::newConnection,this,&Widget::newConnection);
}

void Widget::newConnection()//newConnection信号对应槽函数实现
{
    //获取客户端套接字
    QTcpSocket *s=p->nextPendingConnection();
    //将客户端套接字放入容器
    socketList.push_back(s);
    //程序运行至此,说明服务器与客户端建立了连接
    //如果客户端向服务器发来数据,客户端就会自动发送一个readyRead信号(客户端套接字,QtcpScoket),就可以将该信号连接到自定义的槽函数,读取数据
    connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead);
}

void Widget::readyRead()//readyRead信号对应槽函数实现
{
    //遍历客户端容器,移除无效(断开连接)客户端
    for(int i=0;i<socketList.count();i++){
                            //获取容器元素个数的函数
        //判读连接状态,state函数返回值是一个枚举,值为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));//fromLocal8Bit字节转为QString
                //将发送的消息转发给其他客户端
                for(int i=0;i<socketList.count();i++){
                    socketList.at(i)->write(msg);
                }
            }
        }
   // p->close();//关闭服务器
}

widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>470</width>
    <height>439</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QListWidget" name="listWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>20</y>
     <width>441</width>
     <height>321</height>
    </rect>
   </property>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>380</y>
     <width>81</width>
     <height>31</height>
    </rect>
   </property>
   <property name="text">
    <string>端口号:</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEdit">
   <property name="geometry">
    <rect>
     <x>70</x>
     <y>380</y>
     <width>221</width>
     <height>31</height>
    </rect>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>310</x>
     <y>380</y>
     <width>141</width>
     <height>31</height>
    </rect>
   </property>
   <property name="text">
    <string>启动服务器</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

main.cpp

#include "widget.h"

#include <QApplication>

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

widget.h

#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_pushButton_clicked();
public slots:
    void newConnection();//newConnection()槽函数
    void readyRead();//readyRead()信号槽函数

private:
    Ui::Widget *ui;
    //实例化一个服务器指针
    QTcpServer *p;
    //定义存放客户端套接字的容器
    QList<QTcpSocket *> socketList;
};
#endif // WIDGET_H

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

室内灰尘对老人小孩危害不容忽视,资深家政推荐除灰尘空气净化器

正所谓“病从口入&#xff0c;尘从窗入”&#xff0c;室内灰尘问题不容小觑。尤其是对老人和小孩来说&#xff0c;灰尘中的有害物质更是威胁健康的重要因素。近期天气炎热&#xff0c;家家户户每天都会开窗通风&#xff0c;然而这也带来了灰尘和毛絮的问题。即使每天打扫&#…

使用asyncua模块的call_method方法调用OPC UA的Server端方法报错:asyncio.exceptions.TimeoutError

使用asyncua模块的call_method方法调用OPC UA的Server端方法报错&#xff1a;asyncio.exceptions.TimeoutError 报错信息如下&#xff1a; Traceback (most recent call last): asyncio.run(main()) File “D:\miniconda3\envs\py31013\lib\asyncio\runners.py”, line 44, in…

PID控制算法学习笔记分享

目录 一、参数设定 二、PID计算公式 三、位置式PID代码实现 四、增量式PID代码实现 五、两种控制算法的优缺点 六、PID算法的改进 一、参数设定 比例系数&#xff08;kp&#xff09;&#xff1a;P项的作用是根据当前误差的大小来产生一个控制量。它直接与误差成正比&#…

Codeforces Round 953 (Div. 2) A - C 题解

因为有事只做了A-C&#xff0c;都比较简单&#xff0c;全是很简单的思维&#xff0c;明天有空还会添加上D&#xff0c;如果有人需要可以明天常来看看&#xff01; 进入正题&#xff1a; A. Alice and Books 题意&#xff1a;给你n个数字&#xff0c;将这些数字分到两堆里&am…

【C++初阶路】--- 类和对象(中)

目录 一、this指针1.1 this指针的引出1.2 this指针的特性1.3. C语言和C实现Stack的对比 二、类的6个默认成员函数三、构造函数3.1 概念3.2 特性 一、this指针 1.1 this指针的引出 如下定义一个日期类Date class Date { public://void InitDate(Date* const this, int year …

APP自动化测试-Appium常见操作之详讲

一、基本操作 1、点击操作 示例&#xff1a;element.click() 针对元素进行点击操作 2、初始化&#xff1a;输入中文的处理 说明&#xff1a;如果连接的是虚拟机&#xff08;真机无需加这两个参数&#xff0c;加上可能会影响手工输入&#xff09;&#xff0c;在初始化配置中…

Java--Arrays类

1.数组的工具java.util.Arrays 2.由于数组对象本身并没有什么方法可以供我们调用&#xff0c;但API中提供了一个工具类Arrays供我们使用&#xff0c;从而可以对数据对象进行一些基本的操作。 3.查看JDK帮助文档 4.Arrays类中的方法都是static修饰静态的静态方法&…

minSdkVersion、targetSdkVersion、compileSdkVersion三者的作用解析

minSDK和targetSDK&#xff0c;这两者相当于一个区间。你能够用到targetSDK中最新的API和最酷的新功能&#xff0c;但又需要向后(向下)兼容到minSDK&#xff0c;保证这个区间内的设备都能够正常的执行你的APP。换句话说&#xff0c;想使用Android刚刚推出的新特性&#xff0c;但…

6 PXE高效批量网络装机

6.1部署PXE远程安装服务 在大规模的Liunx应用环境中&#xff0c;如web群集&#xff0c;分布式计算等&#xff0c;服务器往往并不配备光驱设备&#xff0c;在这种情况下&#xff0c;如何为数十乃至上百台服务器裸机快速安装系统呢&#xff1f;传统的USB光驱&#xff0c;移动硬盘…

零编程数据可视化展示:十个简易案例!

数据可视化是呈现数据内在价值的最终手段。数据可视化实例利用各种图表和图形设计手段&#xff0c;合乎逻辑地展示复杂而不直观的数据。为了让用户直观清楚地了解他们想要的数据及其比较关系&#xff0c;数据可视化实例的呈现至关重要。即时设计整理了10个数据可视化实例&#…

17-C语言中的变量生命周期——自动存储期、青苔存储期、自定义存储期

17-C语言中的变量生命周期——自动存储期、青苔存储期、自定义存储期 文章目录 17-C语言中的变量生命周期——自动存储期、青苔存储期、自定义存储期一、自动存储期示例 二、静态存储期2.1 示例 三、自定义存储期3.1 如何申请内存3.2 如何释放内存3.3 如何清空内存3.4 示例 概念…

【学习DayNa】信息系统开发整理

✍&#x1f3fb;记录学习过程中的输出&#xff0c;坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;指点&#x1f64f; 结构化方法 结构是指系统内各个组成要素之间的相互联系、相互作用的框架。结构化开发方法就是…

需求工程师的基本职责(合集)

需求工程师的基本职责1 职责&#xff1a; 1、负责用户需求调研、用户需求分析&#xff0c;明确用户需求分析&#xff0c;明确用户功能需求、业务需求&#xff0c;转换成软件需求说明。 2、收集、分析、整理、提炼系统需求&#xff0c;能够对业务流程提出优化建议并写成系统功能…

音视频入门基础:H.264专题(1)——H.264官方文档下载

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…

SpringBoot整合Minio(支持公有及私有bucket)

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SpringBoot整合Minio(支持公有及私有bucket) ⏱️ 创作时间&#xff1…

第6章 设备驱动程序(4)

目录 6.5 块设备操作 6.5.5 请求结构 6.5.6 BIO 6.5.7 提交请求 6.5.8 I/O调度 6.5.9 ioctl实现 本专栏文章将有70篇左右&#xff0c;欢迎关注&#xff0c;查看后续文章。 6.5 块设备操作 6.5.5 请求结构 struct request { //放在请求队列上&#xff0…

Go Gin框架

一、Gin介绍 Gin是一个用Go编写的HTTPweb框架。它是一个类似于martini但拥有更好性能的API框架, 优于httprouter&#xff0c;速度提高了近 40 倍。点击此处访问Gin官方中文文档。 二、安装 1、安装Gin go get -u github.com/gin-gonic/gin 2、代码中引入 import "githu…

【Docker】——安装镜像和创建容器,详解镜像和Dockerfile

前言 在此记录一下docker的镜像和容器的相关注意事项 前提条件&#xff1a;已安装Docker、显卡驱动等基础配置 1. 安装镜像 网上有太多的教程&#xff0c;但是都没说如何下载官方的镜像&#xff0c;在这里记录一下&#xff0c;使用docker安装官方的镜像 Docker Hub的官方链…

进阶篇05——存储过程、存储函数、触发器

存储过程 简介 基本语法 创建和调用 -- 创建名为p1的存储过程&#xff0c;小括号里可以跟参数 -- 存储过程个人觉得就是SQL里的函数 create procedure p1() begin-- begin 和 end 之间是封装的SQL语句-- 可以是一条SQL也可以是多条SQLselect * from student; end;-- 调用存储…

【FreeRTOS】估算栈的大小

参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》 目录 估算栈的大小回顾简介计算说明估计函数用到的栈有多大合计 估算栈的大小 回顾 上一篇文章链接&#xff1a;http://t.csdnimg.cn/Cc8b4 传送门: 上一篇文章 上一篇文章创建的三个任务 /* 创建任务&#xff1a;声 *…
最新文章