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

文章目录

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

TCP 通信

QT主要通过QTcpSocket 和 QTcpServer两个类实现服务器和客户端的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"
相关推荐
Hhy_110711 分钟前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio
青少儿编程课堂41 分钟前
蓝桥杯青少组图形化省考报名倒计时·全国青少年信息素养大赛·电子学会图形化考级:校园黑白棋人机对战解析
c++·python·算法·bfs·信息学竞赛
严肃小白兔43 分钟前
Cloudflare 更新 API Token 管理:从最小权限到自动化凭据安全
网络·安全·自动化
YSL07012444 分钟前
C++基础
开发语言·c++
eggwyw2 小时前
关于C++为什么不加入垃圾回收机制解析
开发语言·c++
曦樂~11 小时前
Cpp面筋
c语言·c++
道尔柯南12 小时前
C++ string 类详解:从常用接口到深拷贝,彻底掌握字符串处理
android·java·c++
Linux-lucky13 小时前
45-Linux学习之旅之防火墙与WEB加固
linux·前端·网络·学习·ubuntu
十二15 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
博客zhu虎康16 小时前
实现局域网P2P通信:内网发送消息
网络·网络协议·p2p