QT的TcpServer

Server服务器端

QT版本5.6.1

  1. 界面设计
    alt text
  2. 工程文件:

添加 network 模块

alt text

  1. 头文件引入TcpServer类和TcpSocketQTcpServer和QTcpSocket
#include <QTcpServer>
#include <QTcpSocket>

alt text

  1. 创建server对象并实例化:
   /*h文件中*/QTcpServer *tcpServer;/*cpp文件中*/tcpServer = new QTcpServer(this);

使用This作为父对象,方便结束进程生命周期时,释放内存空间

  1. 构建槽函数:
    alt text
private slots:void newConnection_Slot();void readyRead_Slot();void stateChanged_Slot(QAbstractSocket::SocketState);

: 在C++的类中声明函数时可以不写参数名只写参数类型,但是,在实现时必须写出参数名。例如 : void stateChanged_Slot(QAbstractSocket::SocketState);形参是枚举类型,但是没有具体的形参名

newConnection_Slot: 当有客户端的socket建立连接时,tcpserver会发送newConnection()信号,触发连接槽函数,用于创建一个新的socket与客户端对接
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnection_Slot()));

void Widget::newConnection_Slot()
{ui->recvEdit->append("Have a clinet connection");QTcpSocket *temptcpSocket = tcpServer->nextPendingConnection();connect(temptcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));connect(temptcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(stateChanged_Slot(QAbstractSocket::SocketState)));// 客户端的ip地址QString ipaddr = temptcpSocket->peerAddress().toString();quint16 port = temptcpSocket->peerPort();// 打印客户端连接的端口信息ui->recvEdit->append("服务端:客户端的ip地址:" + ipaddr);ui->recvEdit->append("服务端:客户端的端口:" + QString::number(port));}

readyRead_Slot : 当有客户端的socket发送数据过来,服务端用来与客户端对接的socket发送数据可读信号readyRead(),触发槽函数,读数据
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));

void Widget::readyRead_Slot()
{//sender()返回触发该函数的信号所属者的指针QTcpSocket *tcpSocket = (QTcpSocket *)sender();QString buf;buf = tcpSocket->readAll();ui->recvEdit->append(buf);}

stateChanged_Slot(QAbstractSocket::SocketState) : 当服务端的socket与客户端断开连接时,会发送连接状态改变信号,触发槽函数

void Widget::stateChanged_Slot(QAbstractSocket::SocketState socketState)
{QTcpSocket *tcpSocket = (QTcpSocket *)sender();switch(socketState){case QAbstractSocket::UnconnectedState:ui->recvEdit->append("connection end");tcpSocket->deleteLater();break;default:break;}}
  1. ui按键槽函数:
    void on_openBt_clicked();void on_colseBt_clicked();void on_sendBt_clicked();

void on_openBt_clicked() : 打开服务端

void Widget::on_openBt_clicked()
{//判断输入的端口号是否为空,为空则直接返回if(ui->portEdit->text().isEmpty()){ui->recvEdit->append("port is empty!!");return;}//启动监听,QHostAddress::Any表示所有IP地址tcpServer->listen(QHostAddress::Any, ui->portEdit->text().toUInt());ui->recvEdit->append("open successful");ui->openBt->setEnabled(false);ui->colseBt->setEnabled(true);
}

on_colseBt_clicked : 关闭客户端

void Widget::on_colseBt_clicked()
{//关闭tcpserver知识关闭的监听功能,不会有新的客户端建立连接,但是已经建立连接的socket仍然可以通信tcpServer->close();ui->recvEdit->append("close successful");ui->openBt->setEnabled(true);ui->colseBt->setEnabled(false);
}

on_sendBt_clicked : 发送数据

void Widget::on_sendBt_clicked()
{//返回server端与客户端建立连接的所有socketQList <QTcpSocket *> socketList = tcpServer->findChildren<QTcpSocket *>();qDebug() << "tcpSocket 数量:" << socketList.count() << endl;if (socketList.count() == 0) {ui->recvEdit->append("当前没有客户端连接,请先与客户端连接!");return;}foreach (QTcpSocket *tmpTcpSocket, socketList) {// 服务端向每个客户端发送消息tmpTcpSocket->write(ui->sendEdit->text().toUtf8());}ui->recvEdit->append("服务端:" + ui->sendEdit->text());
}

工程源码:

widget.h:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void state_Slot(QAbstractSocket::SocketState);private:Ui::Widget *ui;QTcpServer *tcpServer;private slots:void newConnection_Slot();void readyRead_Slot();void stateChanged_Slot(QAbstractSocket::SocketState);void on_openBt_clicked();void on_colseBt_clicked();void on_sendBt_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);tcpServer = new QTcpServer(this);connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnection_Slot()));
}Widget::~Widget()
{delete ui;
}void Widget::newConnection_Slot()
{ui->recvEdit->append("Have a clinet connection");QTcpSocket *temptcpSocket = tcpServer->nextPendingConnection();connect(temptcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));connect(temptcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(stateChanged_Slot(QAbstractSocket::SocketState)));// 客户端的ip地址QString ipaddr = temptcpSocket->peerAddress().toString();quint16 port = temptcpSocket->peerPort();// 打印客户端连接的端口信息ui->recvEdit->append("服务端:客户端的ip地址:" + ipaddr);ui->recvEdit->append("服务端:客户端的端口:" + QString::number(port));}void Widget::readyRead_Slot()
{//sender()返回触发该函数的信号所属者的指针QTcpSocket *tcpSocket = (QTcpSocket *)sender();QString buf;buf = tcpSocket->readAll();ui->recvEdit->append(buf);}void Widget::stateChanged_Slot(QAbstractSocket::SocketState socketState)
{QTcpSocket *tcpSocket = (QTcpSocket *)sender();switch(socketState){case QAbstractSocket::UnconnectedState:ui->recvEdit->append("connection end");tcpSocket->deleteLater();break;default:break;}}void Widget::on_openBt_clicked()
{if(ui->portEdit->text().isEmpty()){ui->recvEdit->append("port is empty!!");return;}tcpServer->listen(QHostAddress::Any, ui->portEdit->text().toUInt());ui->recvEdit->append("open successful");ui->openBt->setEnabled(false);ui->colseBt->setEnabled(true);
}void Widget::on_colseBt_clicked()
{tcpServer->close();ui->recvEdit->append("close successful");ui->openBt->setEnabled(true);ui->colseBt->setEnabled(false);
}void Widget::on_sendBt_clicked()
{//返回server端与客户端建立连接的所有socketQList <QTcpSocket *> socketList = tcpServer->findChildren<QTcpSocket *>();qDebug() << "tcpSocket 数量:" << socketList.count() << endl;if (socketList.count() == 0) {ui->recvEdit->append("当前没有客户端连接,请先与客户端连接!");return;}foreach (QTcpSocket *tmpTcpSocket, socketList) {// 服务端向每个客户端发送消息tmpTcpSocket->write(ui->sendEdit->text().toUtf8());}ui->recvEdit->append("服务端:" + ui->sendEdit->text());
}

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

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

相关文章

使用Django中的Session和Cookie来传递数据

在Django中&#xff0c;Session和Cookie是两种常用的机制&#xff0c;用于在服务器端和客户端之间传递数据。下面我将简要介绍如何在Django中使用Session和Cookie来传递数据。 1、问题背景 在 Django 中&#xff0c;可以使用 request.POST 来获取表单提交的数据。但是&#xf…

iOS plist文件增删改查

一. plist简介 plist文件&#xff0c;即属性列表文件&#xff0c;全名是Property List&#xff0c;这种文件的扩展名为.plist&#xff0c;因此&#xff0c;通常被叫做plist文件。它是一种用来存储串行化后的对象的文件&#xff0c;在iOS开发中通常用来存储用户设置&#xff0c…

GaussDB数据库SQL系列-复合查询

目录 一、前言 二、复合查询基础 三、实际应用示例 1、使用UNION合并查询结果 2、使用INTERSECT找出共同元素 3、使用EXCEPT排除特定结果 四、高级技巧 1、子查询实例 2、JOIN的应用 五、总结 一、前言 GaussDB是华为自主创新研发的分布式关系型数据库&#xff0c;具…

按键的短按、长按和连续的划分

在实际生活中&#xff0c;我们使用到的按键在短按、长按和按键松开时都会触发不同的功能。按键短按后松开和长按后松开的应用比短按和长按的应用较少&#xff0c;我了解的按键短按后松开和长按后松开的应用是在点动控制和长动控制中。这里主要讨论按键的短按、长按和连续这三种…

postgresql主从复制

用vmware 搭建的两台虚拟机 操作系统&#xff1a;Ubuntu 24.04 Server版 数据库&#xff1a;postgresql 16.2 主库&#xff1a;192.168.2.11 从库&#xff1a;192.168.2.12 如果遇到网络无法上网&#xff0c;可参考一下 Vmware 搭建的Ubuntu 24.04 网络配置-CSDN博客 1.两…

LED显示屏的部件组成及相关知识

LED显示屏作为现代化信息传播的重要载体&#xff0c;在各种场所得到了广泛应用。其功能强大&#xff0c;效果生动&#xff0c;但其背后的部件组成却是复杂而精密的。本文将介绍LED显示屏的主要部件组成及相关知识&#xff0c;以帮助读者更好地理解LED显示屏的工作原理和构造。 …

day07beef-xss之根据beef-xss获取cookies

1.安装 apt-get update apt-get install beef-xss 若报错运行不了尝试 apt remove ruby apt remove beef-xss apt-get install ruby apt-get install ruby-dev libpcap-dev gem install eventmachine apt-get install beef-xss 2.运行 beef-xss 运行成功会自动弹出浏览框。 攻…

提高Rust安装与更新的速度

一、背景 因为rust安装过程中&#xff0c;默认的下载服务器为crates.io&#xff0c;这是一个国外的服务器&#xff0c;国内用户使用时&#xff0c;下载与更新的速度非常慢&#xff0c;因此&#xff0c;我们需要使用一个国内的服务器来提高下载与更新的速度。 本文推荐使用字节…

企业微信集成H5授权登录相关知识(二)

流程&#xff1a; 1.前端请求企业微信获取code&#xff1a;官网网页授权链接 2.企业微信返回的code请求后端判断是否已绑定系统账户 3.后端根据企业微信code&#xff0c;accessToken获得userId 4.userId获取user进行oauth2授权方式进行免密登录 相关知识&#xff1a; 一&a…

SS-PEG-SS可以与多种底物进行反应,生成具有良好稳定性的键合结构

【试剂详情】 英文名称 SS-PEG-SS 中文名称 琥珀酰亚胺丁二酸酯-聚乙二醇-琥珀酰亚胺丁二酸酯 外观性状 由分子量决定&#xff0c;固体或者液体。 分子量 0.4k&#xff0c;0.6k&#xff0c;1k&#xff0c;2k&#xff0c;3.4k&#xff0c;5k&#xff0c;10k&#xff08;可…

初识多线程

1. 前置知识——进程 在学习多线程前需要了解操作系统中的基本知识&#xff0c;这里简单回顾下。 1.1 进程控制块 一个进程对应着一个进程控制块PCB&#xff0c;PCB是一个用于管理和维护进程信息的数据结构&#xff0c;这个数据结构中大致包含下面内容&#xff08;并不完整&…

金仓面对面 | 人大金仓×安硕信息共话金融信用风险管理数字化转型之道

金仓面对面 在数字化浪潮的推动下&#xff0c;人大金仓携手行业先锋&#xff0c;共同开启一场关于创新与转型的思想盛宴——金仓面对面。这不仅是一场对话&#xff0c;更是一次智慧的火花碰撞&#xff0c;一次行业数字化转型洞察的深度挖掘。 行业精英汇聚&#xff1a;我们荣幸…

云南区块链商户平台:抓包技术自制开票工具(二)

前言 上节我们分析了云南区块链商户平台的登录接口以及数据加密、解密&#xff0c;本节我们将构建一个项目框架&#xff0c;将大致的雏形制作出来 说明 由于我们使用开票软件都是在 云南区块链商户平台上操作&#xff0c;如果再开发电脑端就显得没必要&#xff0c;思考良久&…

在线旅游网站,基于 SpringBoot+Vue+MySQL 开发的前后端分离的在线旅游网站设计实现

目录 一. 前言 二. 功能模块 2.1. 登录界面 2.2. 管理员功能模块 2.3. 用户功能模块 三. 部分代码实现 四. 源码下载 一. 前言 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff0c;旅游网站当然…

分布式与集群的区别

先说区别&#xff1a; 分布式是并联工作的&#xff0c;集群是串联工作的。 分布式中的每一个节点都可以做集群。而集群并不一定就是分布式的。 集群举例&#xff1a;比如新浪网&#xff0c;访问的人很多&#xff0c;他可以做一个集群&#xff0c;前面放一个相应的服务器&…

Covalent Network(CQT)通过 “新曙光” 计划实现重要里程碑,增强以太坊时光机,提供 30% 的年化质押收益率

Covalent Network&#xff08;CQT&#xff09;作为集成超过 280 条区块链&#xff0c;并服务于超过 2.8 亿个钱包的领先结构化数据基础设施层&#xff0c;宣布了其战略计划 “新曙光” 中的一个重要进展。随着网络升级并完成了准备工作的 75%&#xff0c;这将为即将部署的以太坊…

JUC下CountDownLatch详解

详细介绍 CountDownLatch是Java并发包java.util.concurrent中提供的一个同步工具类&#xff0c;它允许一个或多个线程等待其他线程完成操作后再继续执行。这个工具类基于一个计数器&#xff0c;计数器的初始值可以由构造函数设定。线程调用countDown()方法会将计数器减1&#x…

uniapp——弹出键盘遮挡住输入框 textarea,处理方法

案例 在写输入框的时候会遇见 键盘遮挡住部分textarea框的一部分&#xff0c;使用cursor-spacing处理即可 修改后&#xff1a; 其他问题&#xff1a; 调起键盘输入时&#xff0c;不希望上方的内容被顶上去 代码 <view class"commentBox" :style"botto…

爬虫学习(4)每日一笑

代码 import requests import re import osif __name__ "__main__":if not os.path.exists("./haha"):os.makedirs(./haha)url https://mlol.qt.qq.com/go/mlol_news/varcache_article?docid6321992422382570537&gameid3&zoneplat&webview…

Linux 认识与学习Bash——3

在Linux bash中&#xff0c;数据流重定向是指将命令的输出从默认的标准输出&#xff08;通常是终端&#xff09;重定向到其他位置&#xff0c;如文件或另一个命令的输入。这是通过使用特定的符号来实现的。例如&#xff0c;>用于将输出重定向到文件&#xff0c;而<用于将…