news 2026/7/15 14:11:55

最简洁完整的Qt服务器和客户端TCP通讯代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
最简洁完整的Qt服务器和客户端TCP通讯代码

服务器端

服务器端通讯用到的对象是QTcpServer和QTcpSocket。

QTcpServer提供了一个基于TCP的服务器,允许接受传入的TCP连接。可以指定端口,也可以让QTcpServer自动选择一个端口。可以监听特定地址或所有机器地址。

首先调用listen()让服务器侦听传入的连接。每次客户端连接到服务器时,都会发出newConnection()信号。然后再调用nextPendingConnection()以接受挂起的连接作为已连接的QTcpSocket。

TCPServer.h

#ifndef TCPSERVER_H #define TCPSERVER_H #include <QObject> #include <QTcpServer> #include <QTcpSocket> #include <QTimer> class TCPServer : public QObject { Q_OBJECT public: explicit TCPServer(QObject *parent = nullptr); ~TCPServer(); void Start(quint32 port); signals: void SendData(QByteArray data); public slots: //有新客户端连接时触发的槽函数 void OnNewCommunication(); //有新客户端断开时触发的槽函数 void OnDisconnected(); //接收到数据时触发的槽函数 void OnReadyRead(); //发送数据槽函数 void OnSendData(QByteArray data); //定时器槽函数,定时向客户端发送数据 void OnTimeOut(); private: void Close(); QTcpServer* m_pTcpServer; //连接的客户端集合 QVector<QTcpSocket*> m_vecTcpSockets; //方便定时向客户端发送消息 QTimer* m_timer; }; #endif // TCPSERVER_H

TCPServer.cpp

#include "TCPServer.h" #include <QDateTime> #include <QDebug> TCPServer::TCPServer(QObject *parent) : QObject(parent) { m_pTcpServer = new QTcpServer(this); //有客户端连接时触发 connect(m_pTcpServer,SIGNAL(newConnection()),this,SLOT(OnNewCommunication())); connect(this,SIGNAL(SendData(QByteArray)),this,SLOT(OnSendData(QByteArray))); m_timer = new QTimer(); m_timer->setInterval(5000); connect(m_timer,SIGNAL(timeout()),this,SLOT(OnTimeOut())); } TCPServer::~TCPServer() { Close(); delete m_pTcpServer; delete m_timer; } void TCPServer::Start(quint32 port) { m_pTcpServer->listen(QHostAddress::Any,port); qDebug()<<"[服务器]服务器已启动,监听端口:"<<port; m_timer->start(); } void TCPServer::OnNewCommunication() { //获取新的连接TcpSocket QTcpSocket* pSocket = m_pTcpServer->nextPendingConnection(); m_vecTcpSockets.push_back(pSocket); //有客户端断开连接时触发 connect(pSocket,SIGNAL(disconnected()),this,SLOT(OnDisconnected())); //接收数据时触发 connect(pSocket,SIGNAL(readyRead()),this,SLOT(OnReadyRead())); qDebug()<<"[服务器]客户端:["<<pSocket->peerAddress().toString()<<"::"<<pSocket->peerPort()<<"]已连接......"; } void TCPServer::OnDisconnected() { QTcpSocket* pSocket = qobject_cast<QTcpSocket*>(sender()); m_vecTcpSockets.removeOne(pSocket); qDebug()<<"[服务器]客户端:["<<pSocket->peerAddress().toString()<<"::"<<pSocket->peerPort()<<"]断开连接......"; pSocket->deleteLater(); } void TCPServer::OnReadyRead() { QTcpSocket* pSocket = qobject_cast<QTcpSocket*>(sender()); if(pSocket->bytesAvailable() <= 0) return; QByteArray arr = pSocket->readAll(); qDebug()<<"[服务器]接收到客户端["<<pSocket->peerAddress().toString()<<"::"<< pSocket->peerPort() <<"]的数据:"<<arr; } void TCPServer::OnSendData(QByteArray data) { foreach (QTcpSocket* pSocket, m_vecTcpSockets) { pSocket->write(data); qDebug()<<"[服务器]向客户端["<<pSocket->peerAddress().toString()<<"::"<< pSocket->peerPort() <<"]发送数据:"<<data; } } void TCPServer::OnTimeOut() { QString context = "["+QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss") + "]: Hello,Client!"; QByteArray bytes; bytes.append(context); emit SendData(bytes); } void TCPServer::Close() { foreach (QTcpSocket* pSocket, m_vecTcpSockets) { pSocket->close(); pSocket->deleteLater(); } m_vecTcpSockets.clear(); if(m_pTcpServer->isListening()) { m_pTcpServer->close(); } }

main.cpp

#include "TCPServer.h" #include <QCoreApplication> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); TCPServer pTcpServer; pTcpServer.Start(8888); return a.exec(); }

客户端

客户端只需要使用QTcpSocket。

QTcpSocket提供了一个TCP套接字,允许您建立TCP连接和传输数据流。

首先调用connectToHost连接服务器,会发送一个connected()信号。然后通过read()和write()可以接受和写入需要传输的数据。

TCPClient.h

#ifndef TCPCLIENT_H #define TCPCLIENT_H #include <QObject> #include <QTcpSocket> #include <QTimer> class TCPClient : public QObject { Q_OBJECT public: explicit TCPClient(QObject *parent = nullptr); ~TCPClient(); void Start(QString ip, quint32 port); signals: void SendData(QByteArray data); public slots: void OnConnected(); void OnDisconnected(); void OnSocketReadyRead(); void OnSendData(QByteArray data); //定时器槽函数,定时向服务器发送数据 void OnTimeOut(); private: QTcpSocket *m_tcpSocket; //方便定时向服务器发送消息 QTimer* m_timer; }; #endif // TCPCLIENT_H

TCPClient.cpp

#include "TCPClient.h" #include <QDateTime> #include <QHostAddress> TCPClient::TCPClient(QObject *parent) : QObject(parent) { m_tcpSocket = new QTcpSocket(this); connect(m_tcpSocket,SIGNAL(connected()),this,SLOT(OnConnected())); connect(m_tcpSocket,SIGNAL(disconnected()),this,SLOT(OnDisconnected())); connect(m_tcpSocket,SIGNAL(readyRead()),this,SLOT(OnSocketReadyRead())); connect(this,SIGNAL(SendData(QByteArray)),this,SLOT(OnSendData(QByteArray))); m_timer = new QTimer(this); m_timer->setInterval(5000); connect(m_timer,SIGNAL(timeout()),this,SLOT(OnTimeOut())); } TCPClient::~TCPClient() { delete m_tcpSocket; delete m_timer; } void TCPClient::Start(QString ip, quint32 port) { m_tcpSocket->connectToHost(QHostAddress(ip), port); } void TCPClient::OnConnected() { qDebug()<<"[客户端]已连接服务器:"<<m_tcpSocket->peerAddress().toString(); //只有客户端连接上之后才能发消息,要不会报异常 //QNativeSocketEngine::write() was not called in QAbstractSocket::ConnectedState m_timer->start(); } void TCPClient::OnDisconnected() { qDebug()<<"[客户端]已从服务器断开:"<<m_tcpSocket->peerAddress().toString(); m_timer->stop(); } void TCPClient::OnSocketReadyRead() { QByteArray bytes = m_tcpSocket->readAll(); qDebug()<<"[客户端]从服务器接收到数据:"<<bytes; } void TCPClient::OnSendData(QByteArray data) { if(m_tcpSocket->isOpen()) { qDebug()<<"[客户端]向服务器发送数据:"<<data; m_tcpSocket->write(data); } } void TCPClient::OnTimeOut() { if(m_tcpSocket->isOpen()) { QString context = "["+QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss") + "]"+ m_tcpSocket->localAddress().toString() +": Hello,Server!"; QByteArray bytes; bytes.append(context); emit SendData(bytes); } }

main.cpp

#include "TCPClient.h" #include <QCoreApplication> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); TCPClient pTcpClient; pTcpClient.Start("192.168.213.128",8888); return a.exec(); }

说明

其中为了可以实现自动互相发送消息,使用了Qt的Timer对象,每5秒客户端向服务器发送消息,同时服务器也会向连接的客户端发送消息。

运行结果:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 14:10:36

Zotero Scihub插件:学术文献获取的终极自动化解决方案

Zotero Scihub插件&#xff1a;学术文献获取的终极自动化解决方案 【免费下载链接】zotero-scihub A plugin that will automatically download PDFs of zotero items from sci-hub 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-scihub 还在为获取学术文献PDF而…

作者头像 李华
网站建设 2026/7/15 14:09:55

【idea做lua编辑器】1.同时安装EmmyLua和Luanalysis这2个插件IDEA就报错打不开,保留EmmyLua插件即可 2.还有个插件叫EmmyLuaCodeStyle 3.坚持用jb

IDEA断点调试1.安装的插件2.配置-- 此文件不要提交&#xff0c;会影响其他人 ---- 自己本地添加自己的调试信息 package.cpath package.cpath .. ;C:/Users/LX-SLM/AppData/Roaming/JetBrains/IntelliJIdea2025.3/plugins/IntelliJ-EmmyLua/debugger/emmy/windows/x64/?.dll …

作者头像 李华
网站建设 2026/7/15 14:09:54

Reloaded-II终极指南:从零开始构建跨平台游戏模组框架

Reloaded-II终极指南&#xff1a;从零开始构建跨平台游戏模组框架 【免费下载链接】Reloaded-II Universal .NET Core Powered Modding Framework for any Native Game X86, X64. 项目地址: https://gitcode.com/gh_mirrors/re/Reloaded-II Reloaded-II是一个基于.NET C…

作者头像 李华
网站建设 2026/7/15 14:07:53

政策文本智能解构实战手册:从《十四五数字经济发展规划》到落地执行表,ChatGPT+人工复核双轨验证流程(政务AI应用白皮书首发)

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;政策文本智能解构的范式跃迁与政务AI治理新基座 传统政策文本解析长期依赖人工摘要、关键词标注与静态规则匹配&#xff0c;面临语义模糊、跨部门术语不一致、时效性滞后等结构性瓶颈。新一代政务AI治理基座以…

作者头像 李华
网站建设 2026/7/15 14:07:48

使用frida hook所有请求链接和响应

/*** v19 - 完整搜索响应捕获 扩展 warn 检测 JSON 文件保存** v18 成果&#xff1a;* - Gson.toJson() 成功序列化 SearchResponse (122KB)* - 搜索响应结构确认: resultGroups[].data[].entity.trackWrapper.track* - warnContent/warnSubType/warnType 字段存在于客…

作者头像 李华
网站建设 2026/7/15 14:06:25

AngularAMD高级用法:自定义Provider和Factory的完整实现

AngularAMD高级用法&#xff1a;自定义Provider和Factory的完整实现 【免费下载链接】angularAMD Facilitate use of RequireJS in AngularJS 项目地址: https://gitcode.com/gh_mirrors/an/angularAMD AngularAMD是一款能够简化RequireJS在AngularJS中使用的实用工具&a…

作者头像 李华