一、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 父子机制、信号槽绑定细节