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端与客户端建立连接的所有socket
    QList <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_OBJECT

public:
    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端与客户端建立连接的所有socket
    QList <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());
}

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

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

相关文章

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统 系统功能 首页 图片轮播 宾馆信息 饮食美食 休闲娱乐 新闻资讯 论坛 留言板 登录注册 个人中心 后台管理 登录注册 个人中心 用户管理 客房登记管理 客房调整管理 休闲娱乐管理 类型信息管理 论坛管理 系统管理 新闻资讯…

Docker-Compose编排LNMP并部署WordPress

前言 随着云计算和容器化技术的快速发展&#xff0c;使用 Docker Compose 编排 LNMP 环境已经成为快速部署 Web 应用程序的一种流行方式。LNMP 环境由 Linux、Nginx、MySQL 和 PHP 组成&#xff0c;为运行 Web 应用提供了稳定的基础。本文将介绍如何通过 Docker Compose 编排 …

BUUCTF---misc---被偷走的文件

1、题目描述 2、下载附件&#xff0c;是一个流量包&#xff0c;拿去wireshark分析&#xff0c;依次点开流量&#xff0c;发现有个流量的内容显示flag.rar 3、接着在kali中分离出压缩包&#xff0c;使用下面命令&#xff0c;将压缩包&#xff0c;分离出放在out3文件夹中 4、在文…

Java -- (part21)

一.File类 1.概述 表示文件或者文件夹的路径抽象表示形式 2.静态成员 static String pathSeparator:路径分隔符:; static String separator:名称分隔符:\ 3.构造方法 File(String parent,String child) File(File parent,String child) Flie(String path) 4.方法 获…

在M1芯片安装鸿蒙闪退解决方法

在M1芯片安装鸿蒙闪退解决方法 前言下载鸿蒙系统安装完成后&#xff0c;在M1 Macos14上打开闪退解决办法接下来就是按照提示一步一步安装。 前言 重新安装macos系统后&#xff0c;再次下载鸿蒙开发软件&#xff0c;竟然发现打不开。 下载鸿蒙系统 下载地址&#xff1a;http…

Android使用kts上传aar到JitPack仓库

Android使用kts上传aar到JitPack 之前做过sdk开发&#xff0c;需要将仓库上传到maven、JitPack或JCenter,但是JCenter已停止维护&#xff0c;本文是讲解上传到JitPack的方式,使用KTS语法&#xff0c;记录使用过程中遇到的一些坑. 1.创建项目(library方式) 由于之前用鸿神的w…

每日OJ题_贪心算法二⑥_力扣409. 最长回文串

目录 力扣409. 最长回文串 解析代码 力扣409. 最长回文串 409. 最长回文串 难度 简单 给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回 通过这些字母构造成的 最长的回文串 。 在构造过程中&#xff0c;请注意 区分大小写 。比如 "Aa" 不能当做一个…

【Java从入门到精通】Java继承

继承的概念 继承是java面向对象编程技术的一块基石&#xff0c;因为它允许创建分等级层次的类。 继承就是子类继承父类的特征和行为&#xff0c;使得子类对象&#xff08;实例&#xff09;具有父类的实例域和方法&#xff0c;或子类从父类继承方法&#xff0c;使得子类具有父…

Linux 麒麟系统安装

国产麒麟系统官网地址&#xff1a; https://www.openkylin.top/downloads/ 下载该镜像后&#xff0c;使用VMware部署一个虚拟机&#xff1a; 完成虚拟机创建。点击&#xff1a;“开启此虚拟机” 选择“试用试用开放麒麟而不安装&#xff08;T&#xff09;”&#xff0c;进入op…

React Native支持Tailwind CSS 语法

React Native支持Tailwind CSS 语法 一、前沿背景 回想下我们平时按照官方的规范进行书写样式是什么样&#xff1f; 是像下面这样&#xff1a; const MyComponent () > {return (<View><Text style{{ fontSize: 20 }}>开发者演示专用</Text></View…

【论文阅读】Tutorial on Diffusion Models for Imaging and Vision

1.The Basics: Variational Auto-Encoder 1.1 VAE Setting 自动编码器有一个输入变量x和一个潜在变量z Example. 获得图像的潜在表现并不是一件陌生的事情。回到jpeg压缩&#xff0c;使用离散余弦变换&#xff08;dct&#xff09;基φn对图像的底层图像/块进行编码。如果你给…

4 Spring AOP

目录 AOP 简介 传统开发模式 先来看一个需求 解决方案 AOP 图示 Spring 启用 AspectJ 基于 xml 配置 创建 pom.xml 创建 UserService 借口和 UserServiceImpl实现类 创建 LogAdvice 日志通知 创建 log4j.properties 重点&#xff1a;创建 spring-context-xml.xml 配…

【深度学习】第二门课 改善深层神经网络 Week 2 3 优化算法、超参数调试和BN及其框架

&#x1f680;Write In Front&#x1f680; &#x1f4dd;个人主页&#xff1a;令夏二十三 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;深度学习 &#x1f4ac;总结&#xff1a;希望你看完之后&#xff0c;能对…

Go语言基础语法(一):变量的声明与赋值

四种声明 变量声明 Go语言是静态类型语言&#xff0c;因此变量&#xff08;variable&#xff09;是有明确类型的&#xff0c;编译器也会检查变量类型的正确性。在数学概念中&#xff0c;变量表示没有固定值且可改变的数。但从计算机系统实现角度来看&#xff0c;变量是一段或…

Simulink|【免费】虚拟同步发电机(VSG)惯量阻尼自适应控制仿真模型

主要内容 该模型为simulink仿真模型&#xff0c;主要实现的内容如下&#xff1a; 随着风力发电、光伏发电等新能源发电渗透率增加&#xff0c;电力系统的等效惯量和等效阻尼逐渐减小&#xff0c;其稳定性问题变得越来越严峻。虚拟同步发电机&#xff08;VSG&#xff09;技…

win10部署本地大模型langchain+ollama

一、环境 windows10、Python 3.9.18、langchain0.1.9 二、ollama下载 Download Ollama on Windows 0.1.33版本链接https://objects.githubusercontent.com/github-production-release-asset-2e65be/658928958/35e38c8d-b7f6-48ed-8a9c-f053d04b01a9?X-Amz-AlgorithmAWS4-H…

ubuntu搭建node私库Verdaccio

ubuntu搭建node私库Verdaccio Verdaccio 是一个轻量级的私有 npm 代理注册服务器&#xff0c;它是开源的&#xff0c;可以帮助你设置和维护企业内部的 npm 包的存储库。使用 Verdaccio 可以让你完全控制包的发布流程、依赖关系以及访问策略。这篇文章将指导你如何在 Ubuntu 系…

SQL注入漏洞扫描---sqlmap

what SQLMap是一款先进的自动执行SQL注入的审计工具。当给定一个URL时&#xff0c;SQLMap会执行以下操作&#xff1a; 判断可注入的参数。判断可以用哪种SQL注入技术来注入。识别出目标使用哪种数据库。根据用户的选择&#xff0c;读取哪些数据库中的数据。 更详细语法请参考…

领域驱动设计(DDD)笔记(三)后端工程架构

文章链接 领域驱动设计(DDD)笔记(一)基本概念-CSDN博客领域驱动设计(DDD)笔记(二)代码组织原则-CSDN博客领域驱动设计(DDD)笔记(三)后端工程架构-CSDN博客前导 领域驱动设计(Domain Driven Design,简称DDD)是业内主导的业务工程理论。它在各中权威人士被广泛讨论…

leetcode_43.字符串相乘

43. 字符串相乘 题目描述&#xff1a;给定两个以字符串形式表示的非负整数 num1 和 num2&#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。 注意&#xff1a;不能使用任何内置的 BigInteger 库或直接将输入转换为整数。 示例 1: 输入: num1 &q…