⓪編著 :蕭沖

總的來說,Socket 可分為二種模式 : blocking mode, non-blocking mode。

要使socket成為non-blocking mode只要設定ioctlsocket為non-blocking mode就可以,然而,若配合使用了blocking functions,會使得讀/取不到資料時產生WSAEWOULDBLOCK的error。因此若要成功而完整的使用non-blocking mode,就必需配合適當的socket IO models。
Socket I/O 有六種模型:blocking, select, WSAAsyncSelect, WSAEventSelect, overlapped, and completion port。

針對不同的模型,我以一個虛擬的例子來說明: 假設有128條水管可以出水,但每一條出水的時間不同,且有快有慢,若我們的任務是在每一條水管必需各裝3桶水,那麼我們可以達成的方法有:  (人數相當於thread的數量,水管數相當於socket數,水桶相當於傳送或接收的Buffer)

1/ blocking : 請128人,每人帶一個水桶,站在每一條水管前等候,直到每個人都裝完3桶水
2/ WSAAsyncSelect,自行定義一個使用者msg,然後結合至windows msg loop,由winproc中的switch case 來處理。這如同-- 請1個人帶一個水桶站在128條水管前,拼命的裝先出水的水管。
3/ WSAEventSelect,請2個人各自帶一個水桶,站在128條水管前,一人管64條(最多),然後拼命的裝先出水的水管。
4/ overlapped with event,使用WSA_FLAG_OVERLAPPED旗標建立overlapped socket,然後使用overlapped socket functions ( APCs)。請2個人各自帶任意個水桶,在128條水管前,一人管64條(最多),將任意數的水桶放於水管前等被裝水,先被裝滿水的水桶則先被通知提領,這二個人再進行提取。
5/ overlapped with completion routine,使用WSA_FLAG_OVERLAPPED旗標建立overlapped socket,然後使用overlapped socket functions ( APCs) with completion routine。請128個人帶任意個水桶,在每一條水管前,將3個水桶放於水管前等被裝水,先被裝滿水的水桶則請1人馬上來提取處理。
6/ completion port(overlapped),建立一個completion port來queue completed notification packets. 當APCs完成IO後,系統會自動的發一個complete paket到指定的completion port上,此時我們之前所建立好的IO worker thread(等候中,in alartable waiting state,監控我們指定的completion port),便會自動的活化並開始取走queue裡的packet,並依之前指定的completion port handle(此worker thread的參數),從GetQueuedCompletionStatus( )得到一些提領訊息。請128個人帶任意個水桶,在每一條水管前,將3個水桶放於水管前等被裝水,先被裝滿水的水桶則被(1至少數人, NumberOfConcurrentThreads,依cpu的數量來決定比較好)自動的放在空地某一排等被提走。同時間,有1至數個工人一直在監控這個空地,若發現有裝滿的水桶等候被提,則開始努力的提取。


When your application calls WSAAsyncSelect / WSAEventSelect Model on a socket, the socket mode is automatically changed from blocking to the non-blocking mode。

All functions that allow overlapped operation (WSASend, WSARecv, WSASendTo, WSARecvFrom, WSAIoctl) 需要socket本身也是建立為overlapped mode才有overlapped的作用:WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
若非overlapped socket使用這些function,則這些function就等同一般的blocking functions。

If both lpOverlapped and lpCompletionRoutine are NULL, the socket in this function will be treated as a nonoverlapped socket.
arrow
arrow
    全站熱搜

    aftcast 發表在 痞客邦 留言(2) 人氣()