手把手带你做一个自己的网络调试助手(1) - TCP服务器准备

news2024/10/6 6:45:02

程序设计流程图

TCP 服务器

ui界面搭建

Tcp服务器建立连接 - listen() + connect()

1.在构造函数中进行如下初始化:

通过 QNetworkInterface 类的  allAddresses 这一API 获得可用IP地址(包括IPv4 和 IPv6)

然后通过QHostAddress类的  protocol 这一API 进行筛选,只读取IPv4的数据

(QAbstractSocket::IPv4Protocol)

    server = new QTcpServer(this); // 初始化TcpServer对象

    //当有新的客户端接入时候建立连接:
    connect(server,SIGNAL(newConnection()),this,SLOT(on_NewClient_Connect()));
    // 设置控件状态 -> 没连接前不能断开连接
    ui->btnStopListen->setEnabled(false);
    ui->btnDisconnect->setEnabled(false);

    //  获取本机可用的ip
    //QList<QHostAddress> QNetworkInterface::allAddresses()
    QList<QHostAddress> addrs =QNetworkInterface::allAddresses();
    for(QHostAddress tmp:addrs){
     if(tmp.protocol() == QAbstractSocket::IPv4Protocol)  // 协议是IPV4协议才读取
        ui->comboBoxAddr->addItem(tmp.toString()); // 把读取到的ip地址添加到comboBox的框中
    }

 2.处理新的连接的槽函数

//处理新连接槽函数
void Widget::on_NewClient_Connect()
{
    //qDebug()<<"new Cline In";
    if(server->hasPendingConnections()){ //有新的连接接入
    QTcpSocket *connect = server->nextPendingConnection();//获取新的连接的信息
    qDebug()<<"Client Addr:"<<connect->peerAddress().toString()<<" host:"<<connect->peerPort();
    ui->textEditRev->insertPlainText("客户端地址:"+connect->peerAddress().toString()+
                                     "\n端口号:"+QString::number(connect->peerPort()));
    }

}

3.监听按钮槽函数

//监听按键槽函数
void Widget::on_btnListen_clicked()
{

    //QHostAddress addr("10.171.24.231"); // 构造合适类型的ip地址 -- 固定IP
    int port = ui->lineEditPort->text().toInt();
    //if(!server->listen(QHostAddress::Any,port)){ //Any -- 监听任意
     if(!server->listen(QHostAddress(ui->comboBoxAddr->currentText()),port)){ //根据combboBox选择的ip地址监听,QHostAddress(QString) -- 构造出合适对象
      qDebug()<<"listen error";
      return;
    }
      qDebug()<<"listen success";
    //监听成功,设置控件状态
    ui->btnListen->setEnabled(false);
    ui->btnStopListen->setEnabled(true);
    ui->btnDisconnect->setEnabled(true);

}

效果演示:

通过下图可以发现,我们已经成功建立连接并且获得了正确的IP地址和端口号

添加串口被占用弹窗提示

添加代码到监听槽函数

//监听按键槽函数
void Widget::on_btnListen_clicked()
{

    //QHostAddress addr("10.171.24.231"); // 构造合适类型的ip地址 -- 固定IP
    int port = ui->lineEditPort->text().toInt();
    //if(!server->listen(QHostAddress::Any,port)){ //Any -- 监听任意
     if(!server->listen(QHostAddress(ui->comboBoxAddr->currentText()),port)){ //根据combboBox选择的ip地址监听,QHostAddress(QString) -- 构造出合适对象
      qDebug()<<"listen error";
      QMessageBox msgBox;
      msgBox.setWindowTitle("监听失败");
      msgBox.setText("端口号被占用");
      msgBox.exec();
      return;
    }
      qDebug()<<"listen success";
    //监听成功,设置控件状态
    ui->btnListen->setEnabled(false);
    ui->btnStopListen->setEnabled(true);
    ui->btnDisconnect->setEnabled(true);

}

效果演示

Tcp服务器接收

添加信号与槽

在处理新连接槽函数中,添加读取消息的信号与槽

    //建立信号与槽来读取内容:
    connect(connection,SIGNAL(readyRead()),this,SLOT(on_readyRead_hanler()));

实现接收槽函数

//  读取数据的信号处理函数
void Widget::on_readyRead_hanler()
{
    //使用sender() --来获得信号额发出者 -- 局部变量
    QTcpSocket *tmpSock = qobject_cast<QTcpSocket *>(sender());
    QByteArray revData = tmpSock->readAll();
    ui->textEditRev->insertPlainText("客户端: "+revData);
}

效果演示

客户端断开检测

实现方法一 - disconnected

在建立新连接那建立信号连接

connect(connection,SIGNAL(disconnected()),this,SLOT(mdisconnected()));

实现断开检测槽函数

// 断开连接检测
void Widget::mdisconnected()
{
     QTcpSocket *tmpSock = qobject_cast<QTcpSocket *>(sender());
    //qDebug()<<"client  out!";
    ui->textEditRev->insertPlainText("客户端断开!");
    tmpSock->deleteLater(); //资源回收
}

方法二 - statechanged

同上建立信号连接

   connect(connection,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this,SLOT(mstateChanged(QAbstractSocket::SocketState)));

实现断开检测槽函数

void Widget::mstateChanged(QAbstractSocket::SocketState socketState)
{
  qDebug()<<"client  out In state"<<socketState;
  switch (socketState) {
   case QAbstractSocket::UnconnectedState:
   //case QAbstractSocket::ClosingState:
       ui->textEditRev->insertPlainText("客户端断开!");
      break;


  }

实现效果:

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

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

相关文章

前端-a-date-picker如何设置禁选时间段

想要做到如图所示的效果&#xff0c;代码如下&#xff1a; 第一个是只能选择某一天&#xff0c;第二个是只能选择某一个时间段 <a-date-pickerv-model:value"record.onTimeStr":show-time"{ format: HH:mm }"valueFormat"YYYY-MM-DD HH:mm:ss&qu…

【算法小记】深度学习——时间序列数据分析 Time series Data Analysis

在本篇博客中将简单介绍常见的几种循环神经网络和一维卷积神经网络&#xff0c;并使用一些简答的数据进行拟合分析。本文相对适合刚入门的同学&#xff0c;同时也作为自己过去一段时间学习的总结和记录&#xff0c;现在神经网络框架已经非常完善的支持了很多常见和有效的深度学…

【学永远不嫌晚】Linux操作系统,linux教程,动力节点linux,老杜linux

碎碎念 总是遇到一些恶心的事情 看最新教程 老师安装的是 vm17 pro&#xff0c;想着也去安装&#xff0c;搜了一大堆&#xff0c;都指向官网下载。 https://support.broadcom.com/group/ecx/productdownloads?subfamilyVMwareWorkstationPro 安装显示没有 entitlement&#…

“GPT-4o深度解析:技术演进、能力评估与个人体验综述“

文章目录 每日一句正能量前言对比分析模型架构性能应用场景用户体验技术创新社区和生态系统总结 技术能力语言生成能力语言理解能力技术实现总结 个人感受关于GPT-4o的假设性观点&#xff1a;关于当前语言模型的一般性观点&#xff1a; 后记 每日一句正能量 又回到了原点&#…

2024年CKA模拟系统制作 | step-by-step | 1、基础环境准备

目录 一、软件环境 二、虚拟网络环境准备 1、编辑虚拟网络 2、网络设置 三、新建虚拟主机 1、新建目录 2、新建虚拟主机 四、系统安装 1、装载系统镜像 2、开启虚拟机 3、选择语言 4、键盘选择 5、网络配置 6、代理设置 7、设置软件源 8、存储设置 9、名称设置 …

记一次postgresql拼接函数string_agg() 和row_number() 使用

PG两个函数使用需求和简单介绍 需求背景介绍第一个需求背景是这样的需求升级一下接下来讲讲STRING_AGG()基本语法排序 然后我们再说说ROW_NUMBER()基本语法使用 row_number() over (partition by) 进行分组统计使用 row_num限定每组数量 需求背景介绍 第一个需求背景是这样的 …

6、组件通信详解(父子、兄弟、祖孙)

一、父传子 1、props 用法&#xff1a; &#xff08;1&#xff09;父组件用 props绑定数据&#xff0c;表示为 v-bind:props"数据" &#xff08;v-bind:简写为 : &#xff0c;props可以任意命名&#xff09; &#xff08;2&#xff09;子组件用 defineProps([props&…

curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL

source ~/.bash_profile flutter clean Command exited with code 128: git fetch --tags Standard error: 错误&#xff1a;RPC 失败。curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8) 错误&#xff1a;预期仍然需要 2737 个字节的正文 fetch-pack: unexpec…

力扣167. 两数之和 II - 输入有序数组

Problem: 167. 两数之和 II - 输入有序数组 文章目录 题目描述思路复杂度Code 题目描述 思路 1.定义左、右指针left、right分别指向数组索引为0和索引为nums.length - 1&#xff0c;定义结果数组int[] res new int[2]用于存储索引; 2.查找&#xff1a;当判断numbers[left] nu…

质量小议38 -- 60岁退休的由来

总是要有个标准&#xff0c;质量更是如些。 标准不是固定不变的&#xff0c;与时俱进。 关键词&#xff1a;当时的人均寿命&#xff1b;渐进式 60岁退休。 22大学毕业开始工作&#xff08;当然可能会更早&#xff09;&#xff0c;到60岁退休&#xff0c;要工作38年。 …

linux:如何硬盘分区扩容

文章目录 1. 前言2. 硬盘分区2.1 查看硬盘2.2 分区2.3 格式化 3. 硬盘分区扩容3.1 创建物理卷3.2 扩展到卷组&#xff08;volume group&#xff09;3.3 合并到待拓展分区3.4 使扩展生效 4 .参考 1. 前言 本文介绍如何将剩余的空间扩展到已有的硬盘分区中。 安装虚拟机的教程&…

【传知代码】BLIP - VLP任务的新框架(论文复现)

前言&#xff1a;在当今人工智能与机器学习领域&#xff0c;视觉-语言预训练&#xff08;Vision-and-Language Pre-training, VLP&#xff09;任务正逐渐崭露头角&#xff0c;其对于推动跨模态智能系统的进步起着至关重要的作用。在这些系统中&#xff0c;图像与文本不再是孤立…

vue -ant -design 卡片是布局 实现动态计算 当前的 左右间距 实现居中

是这样的一个样式 我们使用display :flex 布局的时候 我们全部剧中 display: flex;align-items: center;justify-content: center; 如果是上述的代码来说的话 总是最后的一个也是会居中的 这样就比较丑 我们好像就没有什么好的办法了 我们这自己写的 肯定没有组件牛 如果有…

【Redis学习笔记04】Jedis客户端(上)

Java客户端操作Redis Java生态丰富&#xff0c;自定义的客户端非常多&#xff0c;常见的有Jedis、Lettuce、以及Spring整合后的RedisTemplate&#xff0c;但是对于初学者而言&#xff0c;从Jedis开始入门学习是非常容易上手的&#xff0c;因为Jedis中的API与原生Redis命令高度…

基于栅格占据概率和距离场的机器人覆盖轨迹模拟

基于栅格占据概率和距离场的机器人覆盖轨迹模拟 简介 辐射场模型实现 理论基础 指数函数建模 我们使用指数函数来表示机器人在某个栅格上停留时间对覆盖概率的影响: p ( t ) 1 − e − λ t p(t) 1 - e^{-\lambda t} p(t)1−e−λt 其中 λ \lambda λ 是控制增长速率…

java线程相关知识点

Java多线程涉及以下几个关键点 1.线程生命周期&#xff1a;理解线程从创建到销毁的各个阶段&#xff0c;包括新建、运行、阻塞、等待、计时等待和终止。 2.线程同步&#xff1a;掌握如何使用synchronized关键字和Lock接口来同步代码&#xff0c;防止数据竞争和死锁。 3.线程间通…

vivado HW_DEVICE

硬件设备 描述 在Vivado Design Suite的硬件管理器功能中&#xff0c;每个硬件目标都可以 具有一个或多个Xilinx FPGA设备进行编程或用于调试目的。这个 hw_device对象是通过hw_server打开的hw_target上的物理部分。这个 current_hw_device命令指定或返回当前设备。 相关对象 硬…

Linux系统编程(十二)线程同步、锁、条件变量、信号量

线程同步&#xff1a; 协同步调&#xff0c;对公共区域数据按序访问。防止数据混乱&#xff0c;产生与时间有关的错误。数据混乱的原因 一、互斥锁/互斥量mutex 1. 建议锁&#xff08;协同锁&#xff09;&#xff1a; 公共数据进行保护。所有线程【应该】在访问公共数据前先拿…

Vue3 + TS + Antd + Pinia 从零搭建后台系统(一) 脚手架搭建 + 入口配置

简易后台系统搭建开启&#xff0c;分几篇文章更新&#xff0c;本篇主要先搭架子&#xff0c;配置入口文件等目录 效果图一、搭建脚手架&#xff1a;二、处理package.json基础需要的依赖及运行脚本三、创建环境运行文件四、填充vue.config.ts配置文件五、配置vite-env.d.ts使项目…

微服务开发与实战Day04 - 网关路由和配置

一、网关路由 网关&#xff1a;就是网络的关口&#xff0c;负责请求的路由、转发、身份校验。 在SpringCloud中网关的实现包括两种&#xff1a; 1. 快速入门 Spring Cloud Gateway 步骤&#xff1a; ①新建hm-gateway模块 ②引入依赖pom.xml(hm-gateway) <?xml version…