QT的TcpServer

server/2024/10/22 5:12:21/

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.ppmy.cn/server/30853.html

相关文章

centos 中使用 kubekey 安装 k8s v1.22.12 支持 GPU 调用

环境准备&#xff1a; https://blog.csdn.net/m0_64519023/article/details/138184970 生成配置文件&#xff1a; 中间需要执行 ./kk create config --with-kubernetes v1.22.12 这个命令生成配置文件&#xff0c;保留生成的配置文件中 spec: hosts 下的 node1&#xff0c;将…

EMP.DLL是什么东西?游戏提示EMP.DLL文件缺失怎么解决

emp.dll文件是Windows操作系统中的一种动态链接库文件&#xff0c;它被设计为可以被多个程序共享使用的模块化文件。这种设计旨在提高系统效率&#xff0c;减少内存消耗&#xff0c;并简化软件的维护和更新。DLL文件通常包含了一系列相关的函数和变量&#xff0c;这些函数和变量…

YOLOv5白皮书-第Y6周:模型改进

YOLOv5白皮书-第Y6周&#xff1a;模型改进 YOLOv5白皮书-第Y6周&#xff1a;模型改进一、前言二、我的环境三、更正后的yolov5s.yaml四、运行截图![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/23c3ac6b05d74bfcbea5ec238681710d.png)五、总结 YOLOv5白皮书-第Y6周…

ubuntu20.04安装RabbitMQ 3.11.19+Erlang 25.3.1

1、检查RabbitMQ、Erlang版本 Erlang Version Requirements | RabbitMQ 2、ubuntu20.04对应的是 focal 3、下载安装Erlang 下载地址&#xff1a;http://packages.erlang-solutions.com/erlang/debian/pool/ sudo dpkg -i esl-erlang_25.3-1~ubuntu~focal_amd64.deb sudo apt…

数据结构之“合并两个有序链表”

一、后插法 1、定义&#xff1a; 通过将新节点逐个插入到链表的尾部来创建链表。 2、特点&#xff1a; &#xff08;1&#xff09;每次申请一个新节点&#xff0c;读入相应的数据元素值 &#xff08;2&#xff09;为了使新节点能够插入到表尾&#xff0c;需要增加一个尾指针 r…

如何从0开始创建一个python+Pdm+Django项目

1、安装pdm pip3.10 install pdm或者 pip install pdm2、初始化python项目的配置和环境 pdm init3、在项目中添加 Django 框架 pdm add django4、当前目录创建一个叫做Tesla的Django项目 pdm run django-admin startproject Tesla ./如图 5、编辑pyproject.toml文件&#xff…

笔记-mathtype公式在PDF或打印出来显示不全

原文中的公式&#xff1a; 纸质版打印出来的公式有缺失 问题描述&#xff1a;mathtype公式编辑器所编辑的公式转成PDF或者打印出来有缺失 以下是解决方法的具体描述。 目录 一、准备工作二、操作步骤 一、准备工作 1、工具&#xff1a;mathtype、微软word 二、操作步骤 …

React 之 Suspense

Suspense Suspense 组件我们并不陌生&#xff0c;中文名可以理解为暂停or悬停 , 在 React16 中我们通常在路由懒加载中配合 Lazy 组件一起使用 &#xff0c;当然这也是官方早起版本推荐的唯一用法。 那它暂停了什么&#xff1f; 进行异步网络请求&#xff0c;然后再拿到请求…