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

VC++ 命名管道網路通訊完整實作:從建立連線到異步重疊 I/O

     編輯:關於VC++

命名管道核心優勢

  • 本機/網路雙模式通用
  • 具名引用,發現簡單
  • 支援多用戶端連接同一伺服器實例
  • 全雙工雙向通訊
  • 支援異步重疊 I/O (高併發)

限制:僅 Windows NT 系支援伺服器端建立命名管道 (Win9x 僅能做用戶端)。

通訊流程時序圖

Server                          Client
  │                                │
  ├─ CreateNamedPipe(實例) ──────► │
  │                                ├─ WaitNamedPipe(超時等待)
  │                                │
  ├─ ConnectNamedPipe(阻塞等待) ◄──┤
  │                                ├─ CreateFile(開啟管道檔)
  │                                │
  ◄────────── 連線建立雙方各得 Handle ──►
  │                                │
  ├─ ReadFile/WriteFile (資料交換) ──►
  │                                │
  ├─ DisconnectNamedPipe ────────► │ (或 Client 先 CloseHandle)
  │                                ├─ CloseHandle
  │
  └─ CloseHandle (刪除管道實例)

伺服器端核心代碼


HANDLE hPipe = CreateNamedPipe(
    _T("\\\\.\\pipe\\MyPipe"),           // 本機管道名
    PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED, // 雙向+非緩衝+重疊
    PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, // 位元組模式、阻塞
    PIPE_UNLIMITED_INSTANCES,          // 不限實例數
    4096, 4096,                        // 輸出/輸入緩衝區
    5000,                              // 預設超時 5 秒
    NULL);                             // 安全屬性

if (hPipe == INVALID_HANDLE_VALUE) { /*錯誤*/ }

OVERLAPPED ol = {0}; ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ConnectNamedPipe(hPipe, &ol); // 非阻塞等待連線
// 可用 GetOverlappedResult/WaitForSingleObject 輪詢 ol.hEvent
// 連線成功後:ReadFile/WriteFile 搭配 OVERLAPPED 進行異步收發

用戶端核心代碼


HANDLE hPipe;
while (TRUE) {
    if (WaitNamedPipe(_T("\\\\ServerName\\pipe\\MyPipe"), NMPWAIT_WAIT_FOREVER)) {
        hPipe = CreateFile(
            _T("\\\\ServerName\\pipe\\MyPipe"),
            GENERIC_READ | GENERIC_WRITE,
            0, NULL, OPEN_EXISTING,
            FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED, // 必須 OVERLAPPED 配合伺服器
            NULL);
        if (hPipe != INVALID_HANDLE_VALUE) break;
    }
    Sleep(1000); // 重試間隔
}
// 連線成功,開始 ReadFile/WriteFile (非同步)

關鍵參數:

  • FILE_FLAG_WRITE_THROUGH:強制資料寫入線路,不經快取,確保可靠性
  • FILE_FLAG_OVERLAPPED:啟用非同步 I/O,高併發必備
  • PIPE_UNLIMITED_INSTANCES:允許無限用戶端同時連線

資料收發模式


// 發送
OVERLAPPED olSend = {0}; olSend.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
WriteFile(hPipe, pBuf, nLen, NULL, &olSend);
// 接收
OVERLAPPED olRecv = {0}; olRecv.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ReadFile(hPipe, pBuf, nMax, NULL, &olRecv);
// 完成通知:GetOverlappedResult / WaitForSingleObject / IOCP

斷線與清理順序

  1. 用戶端:CloseHandle(hPipe)
  2. 伺服器:偵測 ReadFile 返回 0 / ERROR_BROKEN_PIPE → DisconnectNamedPipe(hPipe) → CloseHandle(hPipe)
  3. 最後一個實例關閉後,管道自動刪除

常見錯誤與對策

錯誤碼原因對策
ERROR_PIPE_BUSY所有實例忙碌用戶端 WaitNamedPipe 等待;伺服器增加實例上限
ERROR_BROKEN_PIPE對端已關閉正常斷線流程,非錯誤
ERROR_ACCESS_DENIED安全描述子拒絕CreateNamedPipe 傳入 SECURITY_ATTRIBUTES 允許 Everyone
ERROR_MORE_DATA訊息模式下緩衝區不足改用位元組模式或增大緩衝區

進階:IOCP 整合 (高併發伺服器)


HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
// 每新連線:
CreateIoCompletionPort(hPipe, hIOCP, (ULONG_PTR)pContext, 0);
// Worker Thread 池:
GetQueuedCompletionStatus(hIOCP, &bytes, &key, &ol, INFINITE);
// key = pContext (連線上下文),ol = 對應 OVERLAPPED

支援萬級並發連線,CPU 核心數 × 2 Worker Thread 即可。

部署檢查清單

  • [ ] 伺服器/用戶端同網段、防火牆開放 445 (SMB) 或自訂端口
  • [ ] 管道名稱格式統一:\\Server\pipe\Name (網路)、\\.\pipe\Name (本機)
  • [ ] 伺服器以系統管理員/服務帳號執行 (建立管道需權限)
  • [ ] 異步模式下所有 OVERLAPPED 結構與緩衝區生命週期 > I/O 完成
  • [ ] 壓力測試驗證 PIPE_UNLIMITED_INSTANCES 與非分頁池記憶體用量
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved