首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

遠程桌面實時監控系統實現(MFC CSocket 版)

     編輯:關於VC++

專案概述

本系統實現了基於局域網的遠程桌面實時查看功能,採用 C/S 架構:

  • 服務端:運行在被監控電腦,定時截取屏幕並發送
  • 客戶端:監控端,接收數據並渲染顯示,支持多目標切換

核心技術棧:MFC CSocket、GDI 截圖、位圖網絡傳輸、定時器驅動更新。

服務端核心實現

屏幕截取與編碼

void CEmployerSeverDlg::CatchScreen() {
    CDC dc;
    dc.CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
    
    CBitmap bm;
    int Width = GetSystemMetrics(SM_CXSCREEN);
    int Height = GetSystemMetrics(SM_CYSCREEN);
    bm.CreateCompatibleBitmap(&dc, Width, Height);
    
    CDC tdc;
    tdc.CreateCompatibleDC(&dc);
    CBitmap* pOld = tdc.SelectObject(&bm);
    tdc.BitBlt(0, 0, Width, Height, &dc, 0, 0, SRCCOPY);
    tdc.SelectObject(pOld);
    
    // 獲取位圖信息頭
    BITMAP btm;
    bm.GetBitmap(&btm);
    int size = btm.bmWidthBytes * btm.bmHeight;
    
    // 分配緩衝區並提取像素數據
    lpData = new char[size];
    BITMAPINFOHEADER bih = {0};
    bih.biSize = sizeof(BITMAPINFOHEADER);
    bih.biWidth = btm.bmWidth;
    bih.biHeight = btm.bmHeight;
    bih.biPlanes = 1;
    bih.biBitCount = btm.bmBitsPixel;
    bih.biCompression = BI_RGB;
    bih.biSizeImage = size;
    
    GetDIBits(dc.m_hDC, bm, 0, bih.biHeight, lpData, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
}

關鍵點:使用 GetDIBits 直接獲取設備無關位圖(DIB)數據,避免中間文件 I/O,提升傳輸效率。

網絡發送協議

採用簡易雙階段協議:

  1. 發送位圖信息頭(BITMAP 結構,24 字節)
  2. 發送像素數據流(分包循環發送)

客戶端核心實現

數據接收與重構

void CBossSeeClientView::OnGetScreen() {
    if (!m_pRecBMPSocket) return;
    
    // 1. 請求幀數據
    m_pRecBMPSocket->Send("B", 30);  // 請求 BITMAP 信息頭
    
    // 2. 接收 BITMAP 信息頭
    BITMAP btm;
    int ret = m_pRecBMPSocket->Receive(&btm, sizeof(BITMAP));
    if (ret != sizeof(BITMAP)) return;
    
    // 3. 請求像素數據
    m_pRecBMPSocket->Send("D", 30);
    int size = btm.bmWidthBytes * btm.bmHeight;
    lpData = new char[size];
    
    // 4. 循環接收完整數據
    int nBytesRec = 0;
    char* pch = lpData;
    while (nBytesRec < size) {
        int nBytesThisTime = m_pRecBMPSocket->Receive(pch, size - nBytesRec);
        if (nBytesThisTime <= 0) break;
        nBytesRec += nBytesThisTime;
        pch += nBytesThisTime;
    }
    
    // 5. 觸發重繪
    Invalidate();
}

高效渲染顯示

void CClientView::OnDraw(CDC* pDC) {
    if (!lpData) return;
    
    // 構建 BITMAPINFOHEADER
    BITMAPINFOHEADER bih = {0};
    bih.biSize = sizeof(BITMAPINFOHEADER);
    bih.biWidth = btm.bmWidth;
    bih.biHeight = btm.bmHeight;
    bih.biPlanes = 1;
    bih.biBitCount = btm.bmBitsPixel;
    bih.biCompression = BI_RGB;
    bih.biSizeImage = btm.bmWidthBytes * btm.bmHeight;
    
    // 創建兼容位圖並設置像素
    CBitmap tbitmap;
    tbitmap.CreateBitmapIndirect(&btm);
    
    CDC tmemdc;
    tmemdc.CreateCompatibleDC(pDC);
    SetDIBits(tmemdc.m_hDC, tbitmap, 0, btm.bmHeight, lpData, (BITMAPINFO*)&bih, DIB_RGB_COLORS);
    
    // 拉伸繪製適應視圖大小
    CRect trect;
    GetClientRect(&trect);
    CBitmap* lpOldbit = tmemdc.SelectObject(&tbitmap);
    pDC->StretchBlt(0, 0, trect.Width(), trect.Height(),
                    &tmemdc, 0, 0, btm.bmWidth, btm.bmHeight, SRCCOPY);
    tmemdc.SelectObject(lpOldbit);
}

已知問題與優化方向

性能瓶頸分析

環節耗時優化建議
屏幕截取~15-30ms使用 DirectX Desktop Duplication API (Win8+)
數據序列化~5-10ms改用 JPEG/PNG 壓縮(GDI+/libjpeg-turbo)
網絡傳輸視帶寬而定啟用 TCP_NODELAY、調整發送緩衝區、考慮 UDP+FEC
客戶端解碼繪製~10-20ms使用 Direct2D/Direct3D 硬件加速渲染

具體改進計劃

  1. 增量更新:僅傳輸變化矩形區域(需服務端維護上一幀對比)
  2. 視頻編碼:集成 H.264/HEVC 編碼器(如 FFmpeg/Intel Media SDK),大幅降低帶寬
  3. 協議優化:定義二進制協議頭(幀序號、時間戳、壓縮格式、區域數量),支持斷點續傳
  4. 異步 I/O:改用 IOCP/Overlapped I/O 或 CAsyncSocket 避免阻塞 UI 線程
  5. 鼠鍵盤回傳:實現遠程控制功能(輸入事件序列化發送)

安全性考量

  • 生產環境必須添加 TLS 加密傳輸
  • 實現身份認證機制(用戶名/密憑/Token)
  • 服務端安裝需管理員權限,建議簽名驅動級部署
  • 記錄訪問審計日志

總結

本專案展示了 Windows 平台下基於 GDI + Socket 的遠程桌面基礎實現。雖然核心流程通順,但受限於 GDI 性能與原始位圖傳輸帶寬,實際部署需引入現代圖形 API 與視頻編碼技術。代碼結構清晰,適合作為學習網絡編程、GDI 繪圖、MFC Socket 使用的教學案例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved