手动开发一个TCP客户端调试工具(二):客户端实现与逻辑讲解

在上篇文章中,我们简单探讨了 TCP 基础概念和Qt中类的基础内容。本篇将从实战角度出发,围绕一份完整的 Qt/C++ 源代码,逐步讲解一个 TCP 客户端调试工具的实现过程。

该工具具有以下功能特性:

  • 自动连接服务器
  • 定时发送当前时间
  • 接收服务器返回的数据
  • 自动重连机制

通过这段代码,你可以快速构建一个基础调试工具,在日常开发、测试中大有用途。


一、完整代码实现

cpp 复制代码
#include <QCoreApplication>
#include <QTcpSocket>
#include <QDateTime>
#include <QThread>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    const QString host = "127.0.0.1"; // 修改为服务器地址
    const quint16 port = 12345;       // 修改为服务器端口

    QTcpSocket socket;

    while (true) {
        if (socket.state() == QAbstractSocket::UnconnectedState) {
            qDebug() << "尝试连接服务器...";
            socket.connectToHost(host, port);

            if (!socket.waitForConnected(3000)) {
                qDebug() << "连接失败:" << socket.errorString();
                QThread::sleep(3); // 连接失败,3秒后重试
                continue;
            }
            qDebug() << "连接成功,开始发送时间...";
        }

        if (socket.state() == QAbstractSocket::ConnectedState) {
            // 发送当前时间
            QString currentTime = QDateTime::currentDateTime().toString(Qt::ISODate);
            socket.write(currentTime.toUtf8());
            socket.write("\n");

            if (!socket.waitForBytesWritten(1000)) {
                qDebug() << "发送失败:" << socket.errorString();
            } else {
                qDebug() << "发送时间:" << currentTime;
            }

            // 等待服务器是否有返回数据(最多等500ms)
            if (socket.waitForReadyRead(500)) {
                QByteArray response = socket.readAll();
                qDebug() << "收到服务器消息:" << QString::fromUtf8(response).trimmed();
            }

            QThread::sleep(1); // 每秒发送一次
        }

        // 如果状态变成断开,重新尝试连接
        if (socket.state() != QAbstractSocket::ConnectedState) {
            qDebug() << "连接断开,准备重新连接...";
            socket.abort();
        }
    }

    return a.exec(); // 实际不会走到这行
}

二、功能模块详解

1. 连接逻辑

程序首先检查 socket 是否处于未连接状态。若是,则发起连接,连接失败后等待 3 秒重试。这种设计非常适合不稳定的网络环境。

cpp 复制代码
if (socket.state() == QAbstractSocket::UnconnectedState) {
    socket.connectToHost(host, port);
    ...
}

2. 周期性发送当前时间

每次连接成功后,程序会使用 ISO 格式获取当前系统时间,并发送给服务器,发送间隔为 1 秒。该功能可用于测试服务器的接收能力和处理效率。

cpp 复制代码
QString currentTime = QDateTime::currentDateTime().toString(Qt::ISODate);
socket.write(currentTime.toUtf8());

3. 读取服务器响应

客户端在每次发送数据后等待服务器回应,并在 500ms 超时时间内读取数据输出,便于观察服务端反馈。

cpp 复制代码
if (socket.waitForReadyRead(500)) {
    QByteArray response = socket.readAll();
    qDebug() << "收到服务器消息:" << QString::fromUtf8(response).trimmed();
}

4. 连接断线自动重连

一旦通信断开,程序将终止当前 socket 并重新尝试连接,实现自动恢复机制,非常适合长期运行场景。

cpp 复制代码
if (socket.state() != QAbstractSocket::ConnectedState) {
    socket.abort();
}

三、典型应用场景

  • 服务端通信测试:用于验证 TCP 服务是否正常处理请求;
  • 心跳机制模拟:验证服务器对周期性消息的响应处理;
  • 教育演示:帮助学习 TCP 基础通信流程;
  • 服务器稳定性检测:长时间运行该工具,观察服务稳定性。

四、运行示例输出(控制台)

shell 复制代码
尝试连接服务器...
连接成功,开始发送时间...
发送时间:2025-07-31T20:10:00
收到服务器消息: OK
发送时间:2025-07-31T20:10:01
收到服务器消息: OK
...

一旦断开连接:

复制代码
连接断开,准备重新连接...
尝试连接服务器...

📦 代码下载地址

通过网盘分享的文件:命令行Tcp链接测试

链接: https://pan.baidu.com/s/1aBrLz3YA84rCG4ah5TctZw?pwd=jkcf 提取码: jkcf


🔜 下一篇预告:构建图形化 TCP 客户端

在下一篇文章中,我们将基于 Qt 的 GUI 框架(如 QMainWindowQTextEditQPushButton 等控件)搭建一个图形化 TCP 客户端调试工具,实现 IP/端口输入、消息手动发送、接收内容显示等功能,为实际开发中的调试工作提供更友好直观的界面支持。