【QT5 网络编程示例】TCP 通信

文章目录

  • [TCP 通信](#TCP 通信)

TCP 通信

QT主要通过QTcpSocketQTcpServer两个类实现服务器和客户端的TCP 通信。

QTcpSocket 是 Qt 提供的套接字类,看用于建立、管理和操作 TCP 连接。

常用方法

  • connectToHost(host, port):连接到指定服务器。
  • disconnectFromHost():断开连接。
  • write(QByteArray):发送数据。
  • readAll():读取所有可用数据。
  • waitForConnected(int timeout):等待连接成功。
  • waitForReadyRead(int timeout):等待数据可读。

常用信号

  • connected():连接成功时触发。
  • disconnected():连接断开时触发。
  • readyRead():有新数据可读时触发。
  • errorOccurred(QAbstractSocket::SocketError):发生错误时触发。

QTcpServer 是 Qt 提供的 TCP 服务器类,它主要用于监听和接受客户端连接。

常用方法

  • listen(QHostAddress, quint16 port):监听指定 IP 和端口。
  • close():关闭服务器。
  • hasPendingConnections():是否有新的连接请求。
  • nextPendingConnection():获取新的连接对象。

常用信号

  • newConnection():有新的客户端连接时触发。

注意:要使用这两个类需要在项目文件中添加:

cpp 复制代码
QT += network

下面给出一个简单示例:
https://github.com/BinaryAI-1024/QtStudy/tree/master/network/TCP

服务器监听端口 12345,等待客户端连接。 客户端连接服务器并发送 "Hello from client!\n"。 服务器收到消息后打印,并向客户端发送 "Hello from server!\n"。 客户端收到服务器消息后打印。

服务器代码

cpp 复制代码
// tcpserver.h
#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QObject>


class TcpServer : public QObject {
    Q_OBJECT
public:
    explicit TcpServer(QObject *parent = nullptr); 
    ~TcpServer();

    void startServer(quint16 port); // 启动服务器并监听指定端口

private slots:
    void onNewConnection(); // 处理新的客户端连接
    void onReadyRead(); // 处理客户端发送的数据

private:
    QTcpServer *server; // 监听 TCP 连接的服务器对象
    QTcpSocket *clientSocket; // 当前连接的客户端套接字
};

#endif // TCPSERVER_H
cpp 复制代码
// tcpserver.cpp
#include "tcpserver.h"
#include <QDebug>

// 构造函数,初始化 QTcpServer 并连接 newConnection 信号
TcpServer::TcpServer(QObject *parent) : QObject(parent), server(new QTcpServer(this)) {
	//  // 每次有新连接可用时都会发出 newConnection() 信号
    connect(server, &QTcpServer::newConnection, this, &TcpServer::onNewConnection);
}

// 析构函数,关闭服务器
TcpServer::~TcpServer() {
    server->close();
}

// 启动服务器,监听指定端口
void TcpServer::startServer(quint16 port) {
    if (server->listen(QHostAddress::Any, port)) {
        qDebug() << "Server started on port" << port;
    } else {
        qDebug() << "Server failed to start!";
    }
}

// 处理新客户端连接
void TcpServer::onNewConnection() {
    clientSocket = server->nextPendingConnection(); // 获取新连接的客户端套接字

    // 连接客户端的 readyRead 信号(有数据可读时触发)
    connect(clientSocket, &QTcpSocket::readyRead, this, &TcpServer::onReadyRead);

    // 连接客户端的 disconnected 信号(客户端断开连接时触发)
    connect(clientSocket, &QTcpSocket::disconnected, clientSocket, &QTcpSocket::deleteLater);

    qDebug() << "New client connected!";
    clientSocket->write("Hello from server!\n"); // 发送欢迎消息给客户端
}

// 处理客户端发送的数据
void TcpServer::onReadyRead() {
    QByteArray data = clientSocket->readAll(); // 读取客户端数据
    qDebug() << "Received from client:" << data;
}

客户端代码

cpp 复制代码
// tcpclient.h
#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QTcpSocket>
#include <QObject>


class TcpClient : public QObject {
    Q_OBJECT
public:
    explicit TcpClient(QObject *parent = nullptr);
    ~TcpClient();

    void connectToServer(const QString &host, quint16 port); // 连接到指定服务器

private slots:
    void onConnected(); // 处理成功连接到服务器的事件
    void onReadyRead(); // 处理从服务器接收的数据

private:
    QTcpSocket *socket; // 客户端 TCP 套接字对象
};

#endif // TCPCLIENT_H
cpp 复制代码
// tcpclient.cpp
#include "tcpclient.h"
#include <QDebug>

// TcpClient 构造函数,初始化 QTcpSocket 并连接信号槽
TcpClient::TcpClient(QObject *parent) : QObject(parent), socket(new QTcpSocket(this)) {
    connect(socket, &QTcpSocket::connected, this, &TcpClient::onConnected); // 连接成功信号
    connect(socket, &QTcpSocket::readyRead, this, &TcpClient::onReadyRead); // 读取数据信号
}

// TcpClient 析构函数,关闭套接字
TcpClient::~TcpClient() {
    socket->close();
}

// 连接到服务器的指定主机和端口
void TcpClient::connectToServer(const QString &host, quint16 port) {
    socket->connectToHost(host, port);
}

// 处理成功连接到服务器的事件
void TcpClient::onConnected() {
    qDebug() << "Connected to server!";
    socket->write("Hello from client!\n"); // 发送消息给服务器
}

// 处理从服务器接收的数据
void TcpClient::onReadyRead() {
    QByteArray data = socket->readAll();
    qDebug() << "Received from server:" << data;
}

主函数

cpp 复制代码
// main.cpp
#include <QCoreApplication>
#include "tcpserver.h"
#include "tcpclient.h"

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

    // 启动服务器
    TcpServer server;
    server.startServer(12345);

    // 启动客户端,连接到服务器
    TcpClient client;
    client.connectToServer("127.0.0.1", 12345);

    return a.exec();
}

结果:

plaintext 复制代码
Server started on port 12345
New client connected!
Connected to server!
Received from server: "Hello from server!\n"
Received from client: "Hello from client!\n"
相关推荐
端平入洛2 天前
delete又未完全delete
c++
端平入洛3 天前
auto有时不auto
c++
DianSan_ERP4 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
哇哈哈20214 天前
信号量和信号
linux·c++
多恩Stone4 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
呉師傅4 天前
火狐浏览器报错配置文件缺失如何解决#操作技巧#
运维·网络·windows·电脑
gihigo19984 天前
基于TCP协议实现视频采集与通信
网络协议·tcp/ip·音视频
蜡笔小马4 天前
21.Boost.Geometry disjoint、distance、envelope、equals、expand和for_each算法接口详解
c++·算法·boost
超级大福宝4 天前
N皇后问题:经典回溯算法的一些分析
数据结构·c++·算法·leetcode
2501_946205524 天前
晶圆机器人双臂怎么选型?适配2-12寸晶圆的末端效应器有哪些?
服务器·网络·机器人