本文以及另外兩篇相關文章解釋 Windows Sockets 編程方面的一些問題。本文介紹阻塞。其他問題包含在 Windows Sockets:字節排序和 Windows Sockets:轉換字符串文章中。
如果使用 CAsyncSocket 類或從其派生,則您需要自己管理這些問題。如果您使用 CSocket 類或從其派生,則由 MFC 管理它們。阻塞
套接字可以處於“阻塞模式”或“無阻塞模式”。處於阻塞(或同步)模式時,套接字的函數直到可以完成自己的操作時才返回。這稱為“阻塞”,因為函數被調用的套接字在調用返回前無法執行任何操作──它被阻塞了。例如,對 Receive 成員函數的調用可能需要任意長的時間才能完成,因為它要等待發送應用程序來發送(使用 CSocket 或使用帶阻塞的 CAsyncSocke 即是如此)。如果 CAsyncSocket 對象處於無阻塞模式(異步操作),調用會立即返回,而當前錯誤代碼(可使用 GetLastError 成員函數檢索)為 WSAEWOULDBLOCK ,它指出由於模式的原因,調用若不立即返回則將阻塞。( CSocket 永遠不返回 WSAEWOULDBLOCK 。該類為您管理阻塞。)
在 32 位操作系統(如 Windows 95 或 Windows 98)和 16 位操作系統(如 Windows 3.1)下,套接字的行為是不同的。與 16 位操作系統不同,32 位操作系統使用搶占式多任務處理技術並提供多線程運行方式。在 32 位操作系統下,可以將套接字放在單獨的輔助線程中。線程中的套接字可以在不妨礙應用程序中其他活動的情況下阻塞,並且不必在阻塞上花費計算時間。有關多線程編程的信息,請參見文章多線程編程。
注意: 在多線程應用程序中,可以使用 CSocket 的阻塞特性來簡化程序設計,而不影響用戶界面的響應。通過處理主線程中的用戶交互和備用線程中的 CSocket 處理,可以將這些邏輯操作分開。在非多線程的應用程序中,這兩個活動必須合並為單個線程來處理。這通常意味著使用 CAsyncSocket 以根據需要處理通信請求,或重寫 CSocket::OnMessagePending 以在漫長的同步活動中處理用戶操作。
其余的討論針對以 16 位操作系統為目標的程序員:
通常,如果使用的是 CAsyncSocket ,則應避免使用阻塞操作,而應使用異步操作。例如,在異步操作中,從調用 Receive 後接收到 WSAEWOULDBLOCK 錯誤代碼那一刻開始,您將一直等到 OnReceive 成員函數被調用以通知您可以再次讀取。通過回調套接字的適當回調通知函數(如 OnReceive)來完成異步調用。
在 Windows 下,阻塞調用被認為是錯誤的做法。默認情況下,CAsyncSocket 支持異步調用,而且您必須使用回調通知自己管理阻塞。另一方面,CSocket 類是同步的。它抽取 Windows 消息並為您管理阻塞。
有關阻塞的更多信息,請參見 Windows Sockets 規范。有關“On”函數的更多信息,請參見 Windows Sockets:套接字通知和 Windows Sockets:從套接字類派生。
有關更多信息,請參見: