当前位置: 首页 > news >正文

手动开发一个TCP服务器调试工具(一):基础知识与核心类接口

在使用 Qt 进行网络通信开发时,TCP 是最常用、最可靠的协议之一。Qt 提供了丰富的类来支持 TCP 通信,其中最关键的两个类就是:

  • QTcpServer:用于监听客户端连接的 TCP 服务端类;
  • QTcpSocket:用于发送和接收数据的通信类。

本篇文章将围绕这两个类展开,讲清楚它们的接口、作用、使用流程以及开发中的注意事项。


一、QTcpServer:TCP 服务监听类

✦ 类功能概述

QTcpServer 是 TCP 通信中的“门卫”,负责监听指定端口,一旦有客户端发起连接请求,它就会通知你,并把连接交给你处理。

✦ 常用接口函数

函数功能说明
bool listen(const QHostAddress &address, quint16 port)启动监听
void close()停止监听并释放资源
bool isListening() const查询当前是否处于监听状态
QTcpSocket *nextPendingConnection()获取一个新的客户端连接对象

✦ 重要信号

信号发出时机
void newConnection()有客户端连接到达时发出
void acceptError(QAbstractSocket::SocketError)接收连接出错时发出

✦ 示例代码:启动监听

QTcpServer *server = new QTcpServer(this);// 启动监听任意地址上的 12345 端口
server->listen(QHostAddress::Any, 12345);// 连接信号处理新连接
connect(server, &QTcpServer::newConnection, this, [=]() {QTcpSocket *clientSocket = server->nextPendingConnection();qDebug() << "客户端连接:" << clientSocket->peerAddress().toString();
});

二、QTcpSocket:TCP 通信类

✦ 类功能概述

QTcpSocket 是 TCP 通信的“通道”。你可以用它主动连接服务器,也可以用它处理客户端请求,并实现数据的收发。服务器端每个客户端连接都会生成一个独立的 QTcpSocket 实例。

✦ 常用接口函数

函数功能说明
void connectToHost(const QString &hostName, quint16 port)连接服务器(用于客户端)
void disconnectFromHost()主动断开连接
qint64 write(const QByteArray &data)发送数据
QByteArray readAll()读取所有收到的数据
QString peerAddress().toString()获取对方 IP 地址
quint16 peerPort()获取对方端口号

✦ 重要信号

信号触发条件
void readyRead()有新数据可读
void connected()成功建立连接(客户端使用)
void disconnected()对方断开连接
void errorOccurred(QAbstractSocket::SocketError)发生通信错误

✦ 示例代码:接收并响应数据

connect(clientSocket, &QTcpSocket::readyRead, this, [=]() {QByteArray data = clientSocket->readAll();qDebug() << "收到数据:" << data;clientSocket->write("服务器已收到\n");
});

三、典型通信流程总结(服务端)

一个完整的服务端通信流程如下:

  1. 使用 QTcpServer::listen() 启动监听;
  2. 捕捉 newConnection() 信号,调用 nextPendingConnection() 获取 QTcpSocket
  3. 通过 readyRead 信号读取客户端数据;
  4. 使用 write() 方法发送数据;
  5. disconnected 信号中释放资源。

✅ 重点记忆:服务器只监听一次,但每个客户端连接都对应一个独立的 QTcpSocket。


四、开发中的注意事项

✦ 多客户端连接管理

每个连接都需要单独管理。通常做法是将每个连接保存到一个容器中,比如:

QList<QTcpSocket*> clientList;

客户端断开时记得从列表中移除并释放资源:

connect(socket, &QTcpSocket::disconnected, [=]() {clientList.removeOne(socket);socket->deleteLater();
});

✦ socket 生命周期管理

  • 一定不要直接 delete socket 对象,应使用 deleteLater()
  • 不释放资源可能导致内存泄漏。

✦ 与界面线程配合使用

默认情况下,QTcpSocket 应该在其创建的线程中使用。如果你想在子线程中处理连接,必须使用 socket->moveToThread(),并通过信号槽与主线程通信,避免跨线程操作对象。


五、下篇预告

下一篇文章中,我们将基于这套机制构建一个无界面的 TCP 服务程序,支持定时收发消息,实现真正可运行的后台 TCP 服务应用。欢迎继续关注!


http://www.lryc.cn/news/610754.html

相关文章:

  • HTML 如何转 Markdown
  • 【qt5_study】2.使用Qt Designer构造UI界面(信号与槽)
  • 16核32G硬件服务器租用需要多少钱
  • 工业级 CAN 与以太网桥梁:串口服务器CAN通讯转换器深度解析(下)
  • 前端实用工具方法 —— 持续更新中...
  • GPT-5的诞生之痛:AI帝国的现实危机
  • 前端权限设计
  • 云手机的主要功能都包含哪些?
  • MoonBit 月兔 - 云和边缘计算 AI云原生编程语言及开发平台
  • LangChain入门:代理、链、索引
  • WIN QT libsndfile库编译及使用
  • 【教程】Unity AssetBundle 资源管理方法
  • STM32F407VET6学习笔记10:移植smallmodbus
  • 【LeetCode 热题 100】347. 前 K 个高频元素——(解法一)排序截取
  • Redis类型之String
  • 【npm 解决】---- TypeError: crypto.hash is not a function
  • GPS信号捕获尝试
  • 【机器学习深度学习】模型剪枝
  • Python包安全工程实践:构建安全可靠的Python生态系统
  • 【学习笔记】NTP时间同步验证
  • 期权定价全解析:从Black-Scholes到量子革命的金融基石
  • Linux 逻辑卷管理:LVM 原理与 Stratis、VDO 特性对比
  • 基于 Spring Boot 的小区人脸识别与出入记录管理系统实现
  • 力扣经典算法篇-43-全排列(经典回溯问题)
  • css3属性总结和浏览器私有属性
  • Python、Java、C#实现浮点型转换为转型
  • Mysql使用Canal服务同步数据->ElasticSearch
  • 电子秤利用Websocket做为Client向MES系统推送数据
  • 文件编译、调试及库制作
  • 跑yolov5的train.py时,ImportError: Failed to initialize: Bad git executable.