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

📅 2026/7/15 14:11:58
最简洁完整的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; //连接的客户端集合 QVectorQTcpSocket* m_vecTcpSockets; //方便定时向客户端发送消息 QTimer* m_timer; }; #endif // TCPSERVER_HTCPServer.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_castQTcpSocket*(sender()); m_vecTcpSockets.removeOne(pSocket); qDebug()[服务器]客户端:[pSocket-peerAddress().toString()::pSocket-peerPort()]断开连接......; pSocket-deleteLater(); } void TCPServer::OnReadyRead() { QTcpSocket* pSocket qobject_castQTcpSocket*(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_HTCPClient.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秒客户端向服务器发送消息同时服务器也会向连接的客户端发送消息。运行结果