Qt5 C++ TcpSocket 如何判断是服务主动断开tcp socket连接?

文章目录

      • 实现思路
      • 示例代码
      • 代码解释
      • 主要功能和用法
      • 注意事项

在 Qt 5.9.9 的 C++ 开发中,使用 QTcpSocket 时,要判断是服务端主动断开 TCP Socket 连接,可以通过处理 QTcpSocketdisconnected 信号,结合 QTcpSocket 的状态以及相关事件信息来综合判断。以下是具体的实现思路和示例代码:

实现思路

  1. 监听 disconnected 信号:当连接断开时,QTcpSocket 会发出 disconnected 信号,我们可以在槽函数中处理该信号。
  2. 检查连接状态:在 disconnected 信号的槽函数中,检查 QTcpSocket 的状态,判断是否为主动断开。可以结合网络错误码、服务端发送的特定消息等进行判断。
  3. 服务端主动断开的特征判断:例如,如果服务端在断开连接前发送了特定的关闭消息,客户端接收到该消息后就可以知道是服务端主动断开;或者通过网络错误码判断是否是服务端正常关闭连接。
    在这里插入图片描述

示例代码

#include <QtNetwork/QTcpSocket>
#include <QDebug>
#include <QCoreApplication>class MyTcpClient : public QObject
{Q_OBJECT
public:MyTcpClient(QObject *parent = nullptr) : QObject(parent){socket = new QTcpSocket(this);connect(socket, &QTcpSocket::disconnected, this, &MyTcpClient::onDisconnected);connect(socket, &QTcpSocket::readyRead, this, &MyTcpClient::onReadyRead);// 连接到服务端socket->connectToHost("127.0.0.1", 12345);}private slots:void onDisconnected(){// 检查是否是服务端主动断开if (socket->state() == QAbstractSocket::UnconnectedState) {// 可以进一步根据错误码判断if (socket->error() == QAbstractSocket::RemoteHostClosedError) {qDebug() << "Server主动断开连接";} else {qDebug() << "连接断开,错误码:" << socket->errorString();}}}void onReadyRead(){QByteArray data = socket->readAll();// 假设服务端发送 "CLOSE_CONNECTION" 表示主动断开连接if (data == "CLOSE_CONNECTION") {qDebug() << "收到服务端断开连接消息,即将断开连接";socket->disconnectFromHost();}}private:QTcpSocket *socket;
};#include "main.moc"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);MyTcpClient client;return a.exec();
}
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
#include <QDebug>
#include <QCoreApplication>class MyServer : public QTcpServer
{Q_OBJECT
public:explicit MyServer(QObject *parent = nullptr) : QTcpServer(parent) {}protected:void incomingConnection(qintptr socketDescriptor) override{QTcpSocket *socket = new QTcpSocket(this);if (!socket->setSocketDescriptor(socketDescriptor)) {qDebug() << "Failed to set socket descriptor.";delete socket;return;}connect(socket, &QTcpSocket::readyRead, this, [socket]() {QByteArray data = socket->readAll();qDebug() << "Received from client:" << data;// 将收到的数据原样返回给客户端socket->write(data);});connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);}
};#include "server.moc"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);MyServer server;if (!server.listen(QHostAddress::Any, 12345)) {qDebug() << "Server could not start!";} else {qDebug() << "Server started!";}return a.exec();
}
#include <QtNetwork/QTcpSocket>
#include <QDebug>
#include <QCoreApplication>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);QTcpSocket socket;socket.connectToHost(QHostAddress::LocalHost, 12345);if (socket.waitForConnected()) {qDebug() << "Connected to server!";// 向服务器发送消息socket.write("Hello, server!");socket.waitForBytesWritten();if (socket.waitForReadyRead()) {QByteArray data = socket.readAll();qDebug() << "Received from server:" << data;}} else {qDebug() << "Connection failed!";}socket.disconnectFromHost();if (socket.state() != QAbstractSocket::UnconnectedState) {socket.waitForDisconnected();}return a.exec();
}

代码解释

  1. MyTcpClient:继承自 QObject,封装了 QTcpSocket 对象,用于处理与服务端的连接。
  2. 构造函数:创建 QTcpSocket 对象,并连接 disconnectedreadyRead 信号到相应的槽函数。然后尝试连接到服务端。
  3. onDisconnected 槽函数:在连接断开时被调用,检查 QTcpSocket 的状态和错误码。如果错误码为 QAbstractSocket::RemoteHostClosedError,则表示服务端主动断开连接。
  4. onReadyRead 槽函数:在有数据可读时被调用,检查服务端发送的数据。如果收到特定的关闭消息(如 “CLOSE_CONNECTION”),则认为服务端要主动断开连接,调用 disconnectFromHost() 方法断开连接。

主要功能和用法

  • 1 包含必要的头文件
    在使用 QTcpSocket 之前,需要包含相应的头文件,并在 .pro 文件中添加 QT += network 以引入网络模块。
#include <QtNetwork/QTcpSocket>
  • 2 创建 QTcpSocket 对象
QTcpSocket *socket = new QTcpSocket(this);
  • 3 连接到服务器(客户端)
socket->connectToHost(QHostAddress::LocalHost, 12345);
// 可以使用 waitForConnected 等待连接成功
if (socket->waitForConnected()) {qDebug() << "Connected to server!";
} else {qDebug() << "Connection failed!";
}
  • 4.发送数据
QByteArray data = "Hello, server!";
socket->write(data);
// 可以使用 waitForBytesWritten 等待数据发送完成
if (socket->waitForBytesWritten()) {qDebug() << "Data sent successfully!";
}
  • 5.接收数据
// 连接 readyRead 信号到槽函数
connect(socket, &QTcpSocket::readyRead, this, [socket]() {QByteArray data = socket->readAll();qDebug() << "Received data:" << data;
});
  • 6.断开连接
socket->disconnectFromHost();
// 可以使用 waitForDisconnected 等待断开连接完成
if (socket->waitForDisconnected()) {qDebug() << "Disconnected from server!";
}
  • 7.错误处理
connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),[](QAbstractSocket::SocketError socketError) {qDebug() << "Socket error:" << socketError;
});// 获取错误信息
qDebug() << "Error message:" << socket->errorString();

注意事项

  • 上述示例中的错误码判断和特定消息判断只是一种常见的方式,具体的判断逻辑需要根据实际的业务需求和服务端的实现进行调整。
  • 确保服务端和客户端对断开连接的消息和状态处理达成一致,避免出现误解。

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

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

相关文章

Linux环境基础开发工具的使用(三)

五、Linux项目自动化构建工具-make/Makefile make&#xff1a;是一条指令。 makefile&#xff1a;是一个当前目录下的文件。 第一行&#xff1a;依赖关系。 第二行&#xff1a;依赖方法。 clean是空依赖关系。 编译文件清理 背景 会不会写makefile&#xff0c;从一个侧面说…

IDEA + 通义灵码AI程序员:快速构建DDD后端工程模板

作者&#xff1a;陈荣健 IDEA 通义灵码AI程序员&#xff1a;快速构建DDD后端工程模板 在软件开发过程中&#xff0c;一个清晰、可维护、可扩展的架构至关重要。领域驱动设计 (DDD) 是一种软件开发方法&#xff0c;它强调将软件模型与业务领域紧密结合&#xff0c;从而构建更…

源码方式安装llama.cpp及调试

llama.cpp源码方式安装和调试配置 构建和编译 注意这里是cuda&#xff0c;且要开启debug模式 cmake -B build -DGGML_CUDAON -DCMAKE_BUILD_TYPEDebug cmake --build build --config Debug正在编译&#xff1a; 配置launch.json用于调式&#xff1a; 要根据自己的环境路径…

【Ubuntu】GPU显存被占用,但显示没有使用GPU的进程

文章目录 一、问题描述二、解决方案2.1 寻找问题进程2.2 尝试杀死相关进程2.3 投放核弹&#xff0c;一键全杀2.4 再次查看GPU使用情况 参考资料 一、问题描述 今天使用服务器的时候发现gpu被占了很多内存&#xff0c;但是使用 nvidia-smi 命令并没有发现占这么多显存的进程&am…

第4章 4.1 Entity Framework Core概述

4.1.1 什么是ORM ORM (object tralstional mapping ,对象关系映射)中的“对象”指的就是C#中的对象&#xff0c;而“关系”是关系型数据库&#xff0c;“映射”指搭建数据库与C#对象之间的“桥梁”。 比如使用ORM &#xff0c;可以通过创建C#对象的方式把数据插入数据库而不需…

【DeepSeek】本地部署,保姆级教程

deepseek网站链接传送门&#xff1a;DeepSeek 在这里主要介绍DeepSeek的两种部署方法&#xff0c;一种是调用API&#xff0c;一种是本地部署。 一、API调用 1.进入网址Cherry Studio - 全能的AI助手选择立即下载 2.安装时位置建议放在其他盘&#xff0c;不要放c盘 3.进入软件后…

数据结构——字符串匹配KMP

首先明确几个概念&#xff1a; s[ ]: 主串 p[ ]: 模式串(用于匹配) next[ j ]&#xff1a;以p[ j ]结尾的p字符串的前后缀最大匹配值,也是当p[ j1 ]与s[ i ]不匹配时,j指针移动的下一位置。(需要预处理出来) AcWing - 算法基础课 代码如下&#xff1a; #include<iostre…

排查JVM的一些命令

查看JVM相关信息的方法 环境&#xff1a; Win10, jdk17 查看端口的Pid netstat -ano | findstr <端口号>列出当前运行的JVM进程 ## 用于输出JVM中运行的进程状态信息。通过jps&#xff0c;可以快速获取Java进程的PID&#xff08;进程标识符&#xff09;&#xff0c; …

使用vue3框架vue-next-admin导出表格excel(带图片)

想要使用vue3导出表格内容并且图片显示在表格中&#xff08;如图&#xff09;&#xff1a; 步骤如下&#xff1a; 下载安装插件&#xff1a; 安装命令&#xff1a;npm install js-table2excel 引入插件&#xff1a; import table2excel from js-table2excel 使用插件 …

懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)

1.合集懒人精灵本地离线卡密验证系统教程(不联网、安全稳定、省钱、永久免费、无任何限制)&#xff1a;https://www.bilibili.com/video/BV1M6rdYEEog/ 备注&#xff1a; 1.本地离线卡密采用最安全的非对称加解密技术&#xff0c;设备id采用最安全多重混合加密不可逆技术生成&…

基于Flask的租房信息可视化系统的设计与实现

【Flask】基于Flask的租房信息可视化系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网的快速发展&#xff0c;租房市场日益繁荣&#xff0c;信息量急剧增加&#xff…

JUC并发—8.并发安全集合二

大纲 1.JDK 1.7的HashMap的死循环与数据丢失 2.ConcurrentHashMap的并发安全 3.ConcurrentHashMap的设计介绍 4.ConcurrentHashMap的put操作流程 5.ConcurrentHashMap的Node数组初始化 6.ConcurrentHashMap对Hash冲突的处理 7.ConcurrentHashMap的并发扩容机制 8.Concu…

docker 改了镜像源为阿里云,还是下载失败

我是windows系统&#xff0c;在学习docker&#xff0c;刚开始执行docker run hello-world还是失败&#xff0c;然后改了镜像源为阿里云&#xff0c;还是失败&#xff0c;后来去查资料&#xff0c;除了阿里云还配置了很多其他镜像源&#xff0c;才好使 "registry-mirrors&q…

mysql总结

系列文章目录 暂无 前言 mysql面试题的总结以及部分原理&#xff0c;部分图片为网上资源&#xff0c;如侵权请告知删除。 一、MySQL 执行流程 1.连接器&#xff1a;建立连接&#xff0c;管理连接、校验用户身份&#xff1b; 2.查询缓存&#xff1a;查询语句如果命中查询缓存…

【Linux网络编程】应用层协议HTTP(请求方法,状态码,重定向,cookie,session)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux网络编程 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 ​ Linux网络编程笔记&#xff1a; https://blog.cs…

城市地质安全专题连载⑦ | 加强国土空间规划管控,规避城市地质安全风险

作者 | 徐海洋 在国土空间规划中&#xff0c;地质调查扮演着先导性和基础性的角色。它如同一把无形的尺子&#xff0c;衡量着每一寸土地的开发潜力与安全边界&#xff0c;不仅为城市规划提供了科学依据&#xff0c;还在规避地质安全风险、优化资源配置方面发挥着关键作用。然而…

内部知识库:安全协作驱动数字化转型新路径

内容概要 在数字化转型进程中&#xff0c;内部知识库作为信息聚合与分发的核心载体&#xff0c;正通过安全协作与智能权限管理重构企业知识治理模式。其核心价值在于将分散的部门数据、经验文档与业务洞察整合至统一平台&#xff0c;形成可追溯、可共享的企业级知识中台&#…

【分布式理论11】分布式协同之分布式事务(一个应用操作多个资源):从刚性事务到柔性事务的演进

文章目录 一. 什么是分布式事务&#xff1f;二. 分布式事务的挑战三. 事务的ACID特性四. CAP理论与BASE理论1. CAP理论1.1. 三大特性1.2. 三者不能兼得 2. BASE理论 五. 分布式事务解决方案1. 两阶段提交&#xff08;2PC&#xff09;2. TCC&#xff08;Try-Confirm-Cancel&…

ARM Linux平台下 OpenCV Camera 实验

一、硬件原理 1. OV2640 1.1 基本功能 OV2640 是一款低功耗、高性能的图像传感器&#xff0c;支持以下功能&#xff1a; 最高分辨率&#xff1a;200 万像素&#xff08;1600x1200&#xff09;。 输出格式&#xff1a;JPEG、YUV、RGB。 内置图像处理功能&#xff1a;自动曝…

Modbus协议基础

文章目录 1、Modbus协议基础知识1.1、Modbus存储范围1.2、Modbus协议功能码说明1.3、Modbus协议分类及测试 2、ModbusRTU通信报文分析2.1、modbusRTU通信格式 3、Modbus通信库开发4、通信库测试 1、Modbus协议基础知识 1.1、Modbus存储范围 modbus规定&#xff0c;每个存储区…