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

Windows Sockets 網路程式設計 (三):WSAAsyncSelect 非同步模型與程式設計核心

     編輯:關於VC++

一、Windows Sockets 擴充重點

繼承 Berkeley Sockets,新增:

  1. 非同步選擇機制:WSAAsyncSelect 註冊網路事件,事件發生時送指定訊息至視窗程式。
  2. 非同步請求函式:WSAAsyncGetXByY 系列,非阻塞查詢主機/服務資訊。
  3. 阻塞鉤子:阻塞呼叫時進入 BlockingHook 處理訊息迴圈,避免凍結 UI。
  4. 錯誤處理:WSAGetLastError/WSASetLastError 支援多執行緒。
  5. 啟動/終止:WSAStartup/WSACleanup 版本協商。

二、WSAAsyncSelect 詳細用法

int WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent);
lEvent 旗標觸發條件
FD_READ套接字可讀 (資料到達)
FD_WRITE套接字可寫 (緩衝區可用)
FD_OOB帶外資料到達
FD_ACCEPT新連線請求
FD_CONNECT連線完成 (客戶端)
FD_CLOSE連線關閉

範例:WSAAsyncSelect(s, hWnd, WM_USER_SOCK, FD_READ | FD_WRITE); 註銷:lEvent = 0。

三、啟動與版本協商

WORD wVer = MAKEWORD(1,1);
WSADATA wsaData;
if (WSAStartup(wVer, &wsaData) != 0) return;
if (LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1) {
    WSACleanup(); return;
}

多次呼叫 WSAStartup 需保證版本參數一致。

四、非同步資料傳輸範例

視窗程式中處理自訂訊息 UM_SOCK:

case UM_SOCK:
    switch (WSAGETSELECTEVENT(lParam)) {
    case FD_READ:
        len = recv(wParam, buf, sizeof(buf), 0);
        break;
    case FD_WRITE:
        while (send(wParam, buf, len, 0) != SOCKET_ERROR) ;
        break;
    }
    break;

五、錯誤處理建議模式

len = send(s, buf, len, 0);
if (len == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK) {
    // 緩衝區滿,稍後重試或等待 FD_WRITE
}

六、阻塞鉤子與取消阻塞

  • 預設 BlockingHook 只抓取/派發視窗訊息。
  • WSASetBlockingHook 安裝自訂鉤子 (不可呼叫其他 Winsock API,僅能呼叫 WSACancelBlockingCall 取消阻塞)。
  • WSACancelBlockingCall 終結阻塞迴圈。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved