当前位置: 首页 > news >正文

Qt TCP 网络通信详解(笔记)

 

本文重点讲解 QTcpSocketQTcpServer 的使用逻辑、信号槽机制与完整实现流程。
适用于聊天程序、文件传输、远程控制等基础 TCP 通信场景。

一、Qt 网络模块简介

Qt 的网络功能集中在模块 QtNetwork 中。
要使用 TCP 功能,必须在 .proCMakeLists.txt 中引入该模块。 CMakeLists.txt 示例

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Network)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Network)target_link_libraries(target_name PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network)

 二、核心类说明

Qt 的 TCP 通信基于 QTcpServer(服务端)和 QTcpSocket(客户端/连接端)两大类。

类名功能
QTcpServer监听端口、等待客户端连接
QTcpSocket负责数据传输(客户端与每个连接的会话)
QHostAddress表示 IP 地址
QNetworkInterface查询本机网卡地址
QAbstractSocketTCP/UDP 套接字基类

三、通信原理

通信流程如下:

┌────────────────┐        ┌───────────────────┐
│   QTcpServer   │        │     QTcpSocket    │
│ (服务端)     │◀──────▶│  (客户端/连接) │
└────────────────┘        └───────────────────┘↑ newConnection()          ││                          │└── nextPendingConnection()││readyRead() -> readAll()
  • 服务端通过 listen() 开启端口监听;

  • 有客户端连接时,会触发 newConnection() 信号;

  • 使用 nextPendingConnection() 获取一个新的 QTcpSocket

  • 客户端使用 connectToHost() 连接服务器;

  • 通信时通过信号 readyRead() 读取数据,通过 write() 发送。


四、服务端实现

widget.h

#ifndef SERVERWIDGET_H
#define SERVERWIDGET_H#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>QT_BEGIN_NAMESPACE
namespace Ui {
class ServerWidget;
}
QT_END_NAMESPACEclass ServerWidget : public QWidget
{Q_OBJECTpublic:explicit ServerWidget(QWidget *parent = nullptr);~ServerWidget();private slots:void onNewConnection();   // 客户端连接void onReadyRead();       // 客户端发送消息private:Ui::ServerWidget *ui;QTcpServer *server;       // 监听对象QTcpSocket *socket;       // 通信套接字
};#endif // SERVERWIDGET_H

widget.cpp

#include "serverwidget.h"
#include "ui_serverwidget.h"
#include <QMessageBox>
#include <QDebug>ServerWidget::ServerWidget(QWidget *parent): QWidget(parent), ui(new Ui::ServerWidget), server(new QTcpServer(this))
{ui->setupUi(this);// 开启监听if (!server->listen(QHostAddress::AnyIPv4, 8000)) {QMessageBox::critical(this, "错误", "监听失败:" + server->errorString());return;}connect(server, &QTcpServer::newConnection, this, &ServerWidget::onNewConnection);qDebug() << "服务器启动成功,监听端口 8000";
}ServerWidget::~ServerWidget() { delete ui; }void ServerWidget::onNewConnection()
{socket = server->nextPendingConnection();connect(socket, &QTcpSocket::readyRead, this, &ServerWidget::onReadyRead);QString ip = socket->peerAddress().toString();quint16 port = socket->peerPort();ui->logBrowser->append(QString("客户端连接:%1:%2").arg(ip).arg(port));socket->write("连接成功,欢迎来到服务器!\n");
}void ServerWidget::onReadyRead()
{QByteArray data = socket->readAll();QString msg = QString::fromUtf8(data);ui->logBrowser->append("收到客户端:" + msg);socket->write("服务器已收到: " + data);
}

五、客户端实现

client.h

#ifndef CLIENTWIDGET_H
#define CLIENTWIDGET_H#include <QWidget>
#include <QTcpSocket>QT_BEGIN_NAMESPACE
namespace Ui {
class ClientWidget;
}
QT_END_NAMESPACEclass ClientWidget : public QWidget
{Q_OBJECTpublic:explicit ClientWidget(QWidget *parent = nullptr);~ClientWidget();private slots:void onConnectClicked();  // 连接服务器void onSendClicked();     // 发送消息void onReadyRead();       // 接收服务器消息private:Ui::ClientWidget *ui;QTcpSocket *socket;
};#endif // CLIENTWIDGET_H

client.cpp

#include "clientwidget.h"
#include "ui_clientwidget.h"
#include <QHostAddress>
#include <QMessageBox>ClientWidget::ClientWidget(QWidget *parent): QWidget(parent), ui(new Ui::ClientWidget), socket(new QTcpSocket(this))
{ui->setupUi(this);connect(socket, &QTcpSocket::readyRead, this, &ClientWidget::onReadyRead);connect(ui->btnConnect, &QPushButton::clicked, this, &ClientWidget::onConnectClicked);connect(ui->btnSend, &QPushButton::clicked, this, &ClientWidget::onSendClicked);
}ClientWidget::~ClientWidget() { delete ui; }void ClientWidget::onConnectClicked()
{QString ip = ui->ipEdit->text();quint16 port = ui->portEdit->text().toUShort();socket->connectToHost(QHostAddress(ip), port);if (socket->waitForConnected(2000)) {QMessageBox::information(this, "成功", "连接服务器成功!");} else {QMessageBox::critical(this, "失败", "连接超时");}
}void ClientWidget::onSendClicked()
{QString msg = ui->msgEdit->text();socket->write(msg.toUtf8());ui->msgEdit->clear();
}void ClientWidget::onReadyRead()
{QByteArray data = socket->readAll();ui->recvBrowser->append("服务器:" + QString::fromUtf8(data));
}

 六、常用信号槽总结

信号含义
QTcpServer::newConnection()当有新的客户端连接时触发
QTcpSocket::readyRead()当有数据可读时触发
QTcpSocket::connected()连接成功后触发
QTcpSocket::disconnected()连接断开时触发
QTcpSocket::errorOccurred()网络错误时触发

七、常见问题与技巧

问题原因解决办法
客户端连接不上监听 IP/端口错误、防火墙拦截使用 127.0.0.1 测试
readyRead() 不触发服务器未 connect() 信号槽检查 connect 语句
中文乱码字符编码不一致使用 QString::fromUtf8() 转换
多客户端管理每个连接都创建独立 QTcpSocket存入 QList<QTcpSocket*>
UI 卡顿长时间操作在主线程中执行QThreadQTimer::singleShot()

八、消息交互逻辑总结

[客户端] connectToHost() → 发送连接请求↓
[服务端] newConnection() → 获取 socket↓
[服务端] readyRead() → 接收消息并反馈↓
[客户端] readyRead() → 显示服务器返回

Qt 的网络模块基于 事件循环,通信全程异步进行,不会阻塞 UI。

九、快速调试建议

  1. 本地测试使用:

    IP: 127.0.0.1
    Port: 8000
    
  2. 服务端启动 → 客户端再连接;

  3. 若连接失败,可使用命令:

    netstat -ano | find "8000"
    

    确认端口监听是否成功;

  4. 建议开启 Qt 的调试输出:

    qDebug() << socket->state();
    

十、总结

功能使用类触发信号典型函数
监听连接QTcpServernewConnection()listen()
获取连接QTcpServernextPendingConnection()
连接服务器QTcpSocketconnected()connectToHost()
发送消息QTcpSocketwrite()
接收消息QTcpSocketreadyRead()readAll()

 总结一句话
QTcpServer 管理连接,QTcpSocket 管理通信。
Qt 的 TCP 模型是“信号槽 + 异步事件循环”,
不需要多线程,也能高效、优雅地完成网络交互。

 

http://www.dtcms.com/a/531733.html

相关文章:

  • RandLA-net-pytorch 复现
  • Rocky 9 安装 Elasticsearch分布式集群基于非安全特性
  • 使用现代C++构建高效日志系统的分步指南
  • Nacos 环境搭建:从单机开发到集群生产部署
  • OpenWrt | 实现限制只有指定设备才能访问 luci 和 使用 SSH 等方式管理设备的方法
  • 数据库圣经-----最终章JDBC
  • 小贷做网站客户推广渠道有哪些
  • SAP SD交货单明细查询接口分享
  • Java Spring原理 --- Bean的作用域,Bean的生命周期,Spring自动配置
  • TCP三次握手与四次挥手通俗理解
  • 电商网站如何设计内容能源产品网站建设多少钱
  • 门户网站的发布特点网站子栏目设计
  • 赣州企业网站建设公司苏州网站定制公司哪家好
  • 网页设计与网站建设的课后习题答案外贸 企业网站 建设
  • 呼伦贝尔网站建设平台海口网站运营托管费用
  • 网站外包费用怎么做分录个人做广播网站需要注意什么
  • 教育网站设计欣赏建一个公司网站要多少钱
  • 广州快速建站公司推荐做关于植物的网站
  • 厦门网站建设哪家专业黔东南小程序开发公司
  • 网站开发公司安心加盟苏州排名搜索优化
  • 响应式网站公司怎么做网站
  • 老师问我做网站用到什么创新技术江苏网站建设空间
  • wordpress 菜单没了网站关键词排名seo
  • 立网站系网站开发用什么工具好
  • html 网站开发软件网站永久免费建站
  • 万网网站开发世界500强企业中国有哪些
  • 漳州招商局规划建设局网站饿了么网站做生鲜吗
  • 官方网站优化方法字体设计转换器
  • 丽江网站建设c3sales软件app开发培训
  • 网站建设培训相关资料进入wordpress后台