Qt多線程TCP服務器實現指南

在Qt中實現多線程TCP服務器可以通過為每個客戶端連接分配獨立的線程來處理,以提高并發性能。以下是一個分步實現的示例:

1. 自定義工作線程類(處理客戶端通信)

// workerthread.h
#include <QObject>
#include <QTcpSocket>
#include <QThread>class WorkerThread : public QObject
{Q_OBJECT
public:explicit WorkerThread(qintptr socketDescriptor, QObject *parent = nullptr);public slots:void processConnection();signals:void dataReceived(const QByteArray &data);void finished();private:qintptr m_socketDescriptor;QTcpSocket *m_socket;
};// workerthread.cpp
WorkerThread::WorkerThread(qintptr socketDescriptor, QObject *parent): QObject(parent), m_socketDescriptor(socketDescriptor)
{
}void WorkerThread::processConnection()
{m_socket = new QTcpSocket();if (!m_socket->setSocketDescriptor(m_socketDescriptor)) {emit error(m_socket->error());delete m_socket;return;}connect(m_socket, &QTcpSocket::readyRead, [this]() {QByteArray data = m_socket->readAll();emit dataReceived(data);// 回顯數據示例m_socket->write("Server received: " + data);});connect(m_socket, &QTcpSocket::disconnected, [this]() {m_socket->deleteLater();emit finished();});
}

2. TCP服務器實現(主線程)

// tcpserver.h
#include <QTcpServer>
#include <QList>class TcpServer : public QTcpServer
{Q_OBJECT
public:explicit TcpServer(QObject *parent = nullptr);void startServer(quint16 port);protected:void incomingConnection(qintptr socketDescriptor) override;private:QList<QThread*> m_threads;
};// tcpserver.cpp
TcpServer::TcpServer(QObject *parent) : QTcpServer(parent) {}void TcpServer::startServer(quint16 port)
{if (!listen(QHostAddress::Any, port)) {qDebug() << "Server could not start!";} else {qDebug() << "Server started on port" << port;}
}void TcpServer::incomingConnection(qintptr socketDescriptor)
{QThread *thread = new QThread();WorkerThread *worker = new WorkerThread(socketDescriptor);worker->moveToThread(thread);connect(thread, &QThread::started, worker, &WorkerThread::processConnection);connect(worker, &WorkerThread::finished, thread, &QThread::quit);connect(worker, &WorkerThread::finished, worker, &WorkerThread::deleteLater);connect(thread, &QThread::finished, thread, &QThread::deleteLater);thread->start();m_threads.append(thread);
}

3. 使用服務器(主函數)

#include "tcpserver.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);TcpServer server;server.startServer(1234);return a.exec();
}

關鍵點說明:

  1. 線程分配機制

    • 每個新連接都會創建獨立的QThread
    • 使用moveToThread()將Worker對象移動到新線程
    • 通過信號槽進行跨線程通信
  2. 資源管理

    • 使用deleteLater()確保安全釋放資源
    • 自動回收線程對象(當線程結束時)
    • 連接斷開后自動清理socket
  3. 注意事項

    • 不要跨線程直接操作socket
    • 使用信號槽進行線程間通信
    • 處理異常斷開情況(網絡錯誤)
    • 考慮線程池優化(大量連接時)

高級優化建議:

  1. 使用線程池(QThreadPool + QRunnable):
class ConnectionTask : public QRunnable {
public:ConnectionTask(qintptr descriptor) : m_descriptor(descriptor) {}void run() override {QTcpSocket socket;socket.setSocketDescriptor(m_descriptor);// 處理通信邏輯}
private:qintptr m_descriptor;
};// 在incomingConnection中:
QThreadPool::globalInstance()->start(new ConnectionTask(socketDescriptor));
  1. 連接限流

    • 設置最大線程數
    • 使用等待隊列管理超額連接
  2. 數據協議設計

    • 定義明確的消息邊界
    • 處理粘包/拆包問題
    • 使用異步數據解析
  3. 性能監控

    • 統計線程使用情況
    • 監控連接數/吞吐量
    • 實現優雅關閉機制

這種實現方式能夠有效處理中等規模的并發連接(約數千連接),對于更高性能需求可以考慮:

  • 使用epoll/kqueue等IO多路復用技術
  • 結合異步IO(QAbstractSocket::waitFor…系列函數要謹慎使用)
  • 采用Reactor模式或Proactor模式

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79094.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79094.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79094.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

詳細介紹Python-pandas-DataFrame全部 *功能* 函數

Python-pandas-DataFrame全部 功能 函數 提示&#xff1a;幫幫志會陸續更新非常多的IT技術知識&#xff0c;希望分享的內容對您有用。本章分享的是pandas的使用語法。前后每一小節的內容是存在的有&#xff1a;學習and理解的關聯性。【幫幫志系列文章】&#xff1a;每個知識點…

香港科技大學廣州|可持續能源與環境學域博士招生宣講會—四川大學專場

香港科技大學廣州&#xff5c;可持續能源與環境學域博士招生宣講會—四川大學專場 時間&#xff1a;2025年5月8日&#xff08;星期四&#xff09;16:30開始 地點&#xff1a;四川大學基礎教學樓A座504 宣講嘉賓&#xff1a;肖殿勛 助理教授 一經錄取&#xff0c;享全額獎學金…

裝飾器設計模式(Decorator Pattern)詳解

裝飾器設計模式(Decorator Pattern)詳解 裝飾器模式是一種結構型設計模式,它允許動態地向對象添加額外行為,而無需修改其原始類。這種模式通過包裝對象的方式提供靈活的擴展功能替代繼承。 1. 核心概念 (1)模式定義 裝飾器模式:動態地給一個對象添加一些額外的職責,就…

【SpringMVC】詳解參數傳遞與實戰指南

目錄 1.前言 2.正文 2.1基礎參數傳遞 2.1.1單參數 2.1.2多參數 2.2對象參數綁定 2.2.1自動封裝對象 2.2.2參數別名處理 2.3集合類型處理 2.3.1數組接收 2.3.2List集合接收 2.4JSON參數處理 2.4.1介紹JSON 2.4.2傳遞JSON參數 2.5RESTful風格參數 2.6文件上傳處理…

mysql-窗口函數一

目錄 一、感受一下分組與窗口函數的區別 二、滑動窗口&#xff08;子窗口&#xff09;大小的確認 2.1 分組函數下order by使用 2.2 窗口子句 2.3 執行流程 三、函數使用 窗口函數需要mysql的版本大于等于8才行&#xff0c;可以先檢查一下自己的mysql版本是多少 select ve…

解決在Mac上無法使用“ll”命令

在 macOS 上&#xff0c;ll 命令是一個常見的別名&#xff0c;它通常是指向 ls -l 的。但是&#xff0c;如果你看到 zsh: command not found: ll&#xff0c;這意味著你當前的 zsh 配置中沒有設置 ll 作為別名。 解決方法&#xff1a; 1. 使用 ls -l 命令 如果只是想查看目錄…

GTA5(傳承/增強) 13980+真車 超跑 大型載具MOD整合包+最新GTA6大型地圖MOD 5月最新更新

1500超跑載具 1000普通超跑 1500真車超跑 各種軍載具1000 各種普通跑車 船舶 飛機 1000 人物1500 添加式led載具1000 超級英雄最新版 添加添加式武器MOD1000 添加地圖MOD500 添加超跑載具2000 當前共計1.2wMOD 4月2日更新 新增770menyoo地圖 當前共計12770 新增48款超級英雄最新…

初學Vue之記事本案例

初學Vue之記事本案例 案例功能需求相關Vue知識案例實現1.實現方法及代碼2.演示 案例收獲與總結 案例功能需求 基于Vue實現記事功能&#xff08;不通過原生JS實現&#xff09; 1.點擊保存按鈕將文本框的內容顯示在特定位置&#xff0c;且清空文本框內容 2.點擊清空按鈕&#x…

一個linux系統電腦,一個windows電腦,怎么實現某一個文件夾共享

下載Samba linux主機名字不能超過15個字符 sudo dnf install samba samba-client -y 創建共享文件夾 sudo mkdir /shared 配置文件 vim /etc/samba/smb.conf [shared] path /shared available yes valid users linux電腦用戶 read only no browsable yes p…

樹莓派5+edge-tts 語音合成并進行播放測試

簡介 Edge-TTS 是一個基于微軟 Edge 瀏覽器的開源文本轉語音(TTS)工具,主要用于將文本轉換為自然流暢的語音。它利用了微軟 Azure 的 TTS 技術,支持多種語言和聲音,同時具備高質量的語音合成能力。這里簡單演示在樹莓派中安裝該項目進行簡單測試。 開源倉庫地址:https:/…

多模態革命!拆解夸克AI相機技術架構:如何用視覺搜索重構信息交互?(附開源方案對比)

一、技術人必看&#xff1a;視覺搜索背后的多模態架構設計 夸克「拍照問夸克」功能絕非簡單的OCRQA拼接&#xff0c;而是一套多模態感知-推理-生成全鏈路系統&#xff0c;其技術棧值得開發者深挖&#xff1a; 視覺編碼器&#xff1a;基于Swin Transformer V2&#xff0c;支持4…

論文閱讀:2024 ICLR Workshop. A STRONGREJECT for Empty Jailbreaks

總目錄 大模型安全相關研究&#xff1a;https://blog.csdn.net/WhiffeYF/article/details/142132328 A STRONGREJECT for Empty Jailbreaks 對空越獄的 StrongREJECT https://arxiv.org/pdf/2402.10260 https://github.com/dsbowen/strong_reject https://strong-reject.re…

AI生成Flutter UI代碼實踐(一)

之前的雜談中有提到目前的一些主流AI編程工具&#xff0c;比如Cursor&#xff0c;Copilot&#xff0c;Trea等。因為我是Android 開發&#xff0c;日常使用Android Studio&#xff0c;所以日常使用最多的還是Copilot&#xff0c;畢竟Github月月送我會員&#xff0c;白嫖還是挺香…

計網分層體系結構(包括OSI,IP,兩者對比和相關概念)

眾所周知&#xff0c;就像我們計算機領域中的任何東西一樣&#xff0c;計算機網絡也是個分層的體系結構&#xff0c;現代提出的結構就兩種——OSI和TCP/IP&#xff0c;我們先來剖析并對比一下這兩種模型&#xff0c;然后總結一下分層思想中的一些共性。 TCP/IP與OSI結構對比圖 …

面向對象的XML綜合練習

快遞包裹配送管理 需求描述 構建一個快遞包裹配送管理系統&#xff0c;完成以下操作&#xff1a; 記錄每個快遞包裹的信息&#xff0c;包括包裹編號、收件人姓名、收件地址和是否已配送。可以添加新的快遞包裹到系統中。標記某個包裹為已配送狀態。統計所有已配送和未配送的…

什么是鴻蒙南向開發?什么是北向開發?

文章目錄 鴻蒙南向開發 vs 北向開發&#xff1a;底層與生態的雙向賦能一、鴻蒙南向開發&#xff1a;連接硬件的底層基石二、鴻蒙北向開發&#xff1a;構建全場景應用生態三、南向與北向&#xff1a;互補與協同四、如何選擇開發方向?結語 鴻蒙南向開發 vs 北向開發&#xff1a;…

Linux常用命令27——userdel刪除用戶

在使用Linux或macOS日常開發中&#xff0c;熟悉一些基本的命令有助于提高工作效率&#xff0c;userdel命令來自英文詞組user delete的縮寫&#xff0c;其功能是刪除用戶信息。在Linux系統中&#xff0c;一切都是文件&#xff0c;用戶信息被保存到了/etc/passwd、/etc/shadow以及…

[藍橋杯 2021 省 AB] 砝碼稱重 Java

import java.util.*;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();int[] w new int[n 1];int sum 0; // 所有砝碼重量之和for (int i 1; i < n; i) {w[i] sc.nextInt();sum w[i];}sc.close()…

今天的python練習題

目錄 一、每日一言 二、練習題 三、效果展示 四、下次題目 五、總結 一、每日一言 晚上8點到的&#xff0c;還是會被感動到&#xff0c;有一位列車員同志在檢票期間&#xff0c;叫我到列車員專座位上去坐&#xff0c;我很感激他&#xff0c;溫暖人心&#xff0c;所以人間填我…