Windows Sockets:阻塞
本文以及另外兩篇相關文章解釋 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 訊息併為您管理阻塞。