第六章 QT基础:4、QT的TCP网络编程

一、TCP 通信原理简介

TCP(Transmission Control Protocol)是一种面向连接的可靠通信协议,主要特性如下:

!NOTE

  • 三次握手建立连接

  • 可靠传输:顺序、无丢包

  • 面向流:数据无结构边界

  • 适用场景:聊天、网页、文件传输


二、Qt 网络模块及常用类

类名 功能说明
QTcpServer 监听端口,接受客户端连接
QTcpSocket 用于客户端和服务端的数据收发
QHostAddress 表示 IP 地址(支持 IPv4/IPv6)

使用前需在 .pro 文件中添加:

pro 复制代码
QT += network

三、TCP 服务端代码

📄 MyTcpServer.h

cpp 复制代码
#ifndef MYTCPSERVER_H
#define MYTCPSERVER_H

#include <QTcpServer>   // TCP服务端类
#include <QTcpSocket>   // TCP套接字类

// 自定义类继承自 QTcpServer
class MyTcpServer : public QTcpServer
{
    Q_OBJECT  // Qt 元对象宏,必须有才能使用信号槽

public:
    explicit MyTcpServer(QObject *parent = nullptr);  // 构造函数
    void startServer(quint16 port);  // 启动服务器

private slots:
    void onNewConnection();       // 有新连接时处理
    void onClientReadyRead();     // 客户端发来数据时处理
    void onClientDisconnected();  // 客户端断开时处理

private:
    QTcpSocket *clientSocket;  // 当前连接的客户端 socket(简化版)
};

#endif // MYTCPSERVER_H

📄 MyTcpServer.cpp

cpp 复制代码
#include "MyTcpServer.h"
#include <QDebug>  // 用于调试输出

// 构造函数:初始化 clientSocket
MyTcpServer::MyTcpServer(QObject *parent)
    : QTcpServer(parent), clientSocket(nullptr) {}

// 启动服务器监听指定端口
void MyTcpServer::startServer(quint16 port)
{
    if (listen(QHostAddress::Any, port)) {
        // QHostAddress::Any 表示监听所有本机地址
        qDebug() << "✅ Server started on port" << port;

        // 当有客户端连接时,发出 newConnection() 信号
        connect(this, &QTcpServer::newConnection,
                this, &MyTcpServer::onNewConnection);
    } else {
        qDebug() << "❌ Server failed to start!";
    }
}

// 有客户端连接时调用
void MyTcpServer::onNewConnection()
{
    // 获取客户端 socket(自动生成)
    clientSocket = nextPendingConnection();

    qDebug() << "🔌 Client connected from"
             << clientSocket->peerAddress().toString();

    // 接收数据信号绑定槽函数
    connect(clientSocket, &QTcpSocket::readyRead,
            this, &MyTcpServer::onClientReadyRead);

    // 客户端断开信号绑定槽函数
    connect(clientSocket, &QTcpSocket::disconnected,
            this, &MyTcpServer::onClientDisconnected);
}

// 客户端有数据时读取
void MyTcpServer::onClientReadyRead()
{
    QByteArray data = clientSocket->readAll();  // 读取所有数据
    qDebug() << "📨 Received:" << data;

    clientSocket->write("✅ Server received: " + data);  // 回传消息
}

// 客户端断开连接处理
void MyTcpServer::onClientDisconnected()
{
    qDebug() << "⚠️ Client disconnected.";
    clientSocket->deleteLater();  // 延迟释放 socket 对象
}

四、TCP 客户端代码(逐行注释)

📄 MyTcpClient.h

cpp 复制代码
#ifndef MYTCPCLIENT_H
#define MYTCPCLIENT_H

#include <QObject>
#include <QTcpSocket>  // TCP 客户端通信类

class MyTcpClient : public QObject
{
    Q_OBJECT

public:
    explicit MyTcpClient(QObject *parent = nullptr);  // 构造函数
    void connectToServer(const QString &host, quint16 port);  // 连接服务器
    void sendMessage(const QString &message);  // 发送消息

private slots:
    void onConnected();      // 连接成功
    void onReadyRead();      // 收到服务器数据
    void onDisconnected();   // 连接断开

private:
    QTcpSocket *socket;      // 客户端 socket 对象
};

#endif // MYTCPCLIENT_H

📄 MyTcpClient.cpp

cpp 复制代码
#include "MyTcpClient.h"
#include <QDebug>

MyTcpClient::MyTcpClient(QObject *parent)
    : QObject(parent)
{
    socket = new QTcpSocket(this);  // 创建 socket,父对象托管内存

    // 信号槽绑定
    connect(socket, &QTcpSocket::connected,
            this, &MyTcpClient::onConnected);

    connect(socket, &QTcpSocket::readyRead,
            this, &MyTcpClient::onReadyRead);

    connect(socket, &QTcpSocket::disconnected,
            this, &MyTcpClient::onDisconnected);
}

// 发起连接
void MyTcpClient::connectToServer(const QString &host, quint16 port)
{
    qDebug() << "🌐 Connecting to server:" << host << ":" << port;
    socket->connectToHost(host, port);  // 异步连接(不会阻塞 UI)
}

// 发送消息
void MyTcpClient::sendMessage(const QString &message)
{
    if (socket->state() == QAbstractSocket::ConnectedState) {
        socket->write(message.toUtf8());  // QString 转 QByteArray
        qDebug() << "➡️ Sent to server:" << message;
    } else {
        qDebug() << "⚠️ Not connected.";
    }
}

// 连接成功
void MyTcpClient::onConnected()
{
    qDebug() << "✅ Connected to server.";
}

// 收到服务器消息
void MyTcpClient::onReadyRead()
{
    QByteArray data = socket->readAll();  // 读取服务器发送内容
    qDebug() << "📩 Server response:" << QString(data);
}

// 断开连接
void MyTcpClient::onDisconnected()
{
    qDebug() << "❌ Disconnected from server.";
}

五、main.cpp 示例调用(测试)

cpp 复制代码
MyTcpServer *server = new MyTcpServer();
server->startServer(12345);  // 启动服务端

MyTcpClient *client = new MyTcpClient();
client->connectToServer("127.0.0.1", 12345);  // 连接服务端
client->sendMessage("Hello from Client!");   // 发送消息

六、总结

  • Qt 中的 TCP 通信机制与基本原理
  • QTcpServer 如何监听 + 接收连接 + 获取 QTcpSocket
  • QTcpSocket 如何连接服务器 + 发送接收数据
  • C++ 构造函数、QObject 父子机制、信号槽绑定细节
相关推荐
Dream of maid6 小时前
Python12(网络编程)
开发语言·网络·php
minji...7 小时前
Linux 线程同步与互斥(三) 生产者消费者模型,基于阻塞队列的生产者消费者模型的代码实现
linux·运维·服务器·开发语言·网络·c++·算法
运维行者_8 小时前
OpManager MSP NetFlow Analyzer集成解决方案,应对多客户端网络流量监控挑战
大数据·运维·服务器·网络·数据库·自动化·运维开发
dashizhi20159 小时前
共享文件禁止拖动本地磁盘、共享文件禁止另存为、禁止打印共享文件、禁止复制共享文件的方法
运维·服务器·网络·安全·电脑
网教盟人才服务平台9 小时前
AI 全面重塑网络攻防生态,智能安全进入深度对抗时代
网络·人工智能·安全
老歌老听老掉牙12 小时前
PyQt5+Qt Designer实战:可视化设计智能参数配置界面,告别手动布局时代!
python·qt
头铁的伦12 小时前
QNX 网络模型
linux·网络·车载系统
小贾要学习12 小时前
【Linux】TCP网络通信编程
linux·服务器·网络·c++·网络协议·tcp/ip
vortex512 小时前
构建可审计、可分层、可扩展的SSH身份管理体系
网络·ssh·php
Hello_Embed13 小时前
嵌入式上位机开发入门(十九):Socket 状态检测与断线重连
网络·单片机·网络协议·tcp/ip·嵌入式