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

WinSock 網路程式設計核心:阻塞/非阻塞、異步選擇與 MFC CSocket

     編輯:關於C語言

WinSock API 三大分類

  1. Berkeley Socket 核心函式:
    • 網路 I/O:accept、connect、send/recv、sendto/recvfrom、select、closesocket。
    • 本地設定:bind、listen、getsockopt/setsockopt、getpeername/getsockname、位址轉換 htonl/ntohl 等。
  2. 資料庫查詢函式: gethostbyname、getservbyname 等解析域名/服務/協定,預設阻塞,故提供異步版本 WSAAsyncGetHostByName 等。
  3. Windows 專用擴展: WSAAsyncSelect(事件驅動)、WSAIsBlocking、WSAGetLastError 等。

阻塞與非阻塞模型

模型特徵適用場景
阻塞函式不返回直到完成;主執行緒訊息泵被凍結簡單用戶端、獨立執行緒處理連線
非阻塞立即返回,WSAEWOULDBLOCK 表示需等待單執行緒多連線、GUI 應用程式
異步 (WSAAsyncSelect)指定視窗與訊息,事件發生時通知MFC 單執行緒 Socket 應用首選
重疊 I/O (Overlapped)WSAEventSelect/WSASend + 完成埠 (IOCP)高效能伺服器、大量並發連線

WSAAsyncSelect 事件驅動模型詳解

int WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent);
// lEvent 組合:FD_READ | FD_WRITE | FD_ACCEPT | FD_CONNECT | FD_CLOSE | FD_OOB

呼叫後,Socket 自動轉為非阻塞。指定事件發生時,Windows 送 wMsg 到 hWnd,wParam 為 Socket,lParam 低字為事件,高字為錯誤碼。

MFC CSocket/CAsyncSocket 封裝

  • CAsyncSocket:薄包裝,繼承可覆寫 OnReceive/OnAccept/OnConnect 等虛擬函式,內部使用 WSAAsyncSelect,適合單執行緒 GUI 應用。
  • CSocket:繼承 CAsyncSocket,增加同步阻塞介面(Send/Receive 內部處理等待),並支援 CArchive 序列化,**但不支援多執行緒並發呼叫同一 Socket 物件**。
  • 兩者皆在建構時自動呼叫 AfxSocketInit 載入 Winsock DLL。

常見陷阱

  • 阻塞 Socket 在 GUI 執行緒: 導致介面凍結,必須移至工作執行緒或改用異步模型。
  • CSocket 序列化跨平台: CArchive 格式為 MFC 專有,跨語言/平台需自定協定(如 Protocol Buffers、JSON)。
  • FD_WRITE 誤區: 連線建立後立即觸發一次,之後僅在發送緩衝區從滿→有空間時觸發,**非「隨時可寫」**。
  • 優雅關閉: 呼叫 ShutDown(SD_SEND) 發送 FIN,等待 OnReceive 返回 0(對方也關閉)再 Close。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved