1. 程式人生 > >關於Winsock:重疊的I / O和事件物件

關於Winsock:重疊的I / O和事件物件

Windows套接字2支援重疊I / O,所有傳輸提供程式都支援此功能。 重疊I / O遵循Windows中建立的模型,可以在使用套接字函式建立的套接字上執行,也可以使用WSASocket函式建立的套接字執行,並在dwFlags引數中設定WSA_FLAG_OVERLAPPED標誌。

注意

使用重疊屬性建立套接字對套接字當前是處於阻塞還是非阻塞模式沒有影響。 使用重疊屬性建立的套接字可用於執行重疊I / O操作,因此不會更改套接字的阻塞模式。 由於重疊的I / O操作不會阻塞,因此套接字的阻塞模式與這些操作無關。

對於接收,應用程式使用WSARecv或WSARecvFrom函式來提供要接收資料的緩衝區。 如果在網路接收到資料之前釋出了一個或多個緩衝區,則該資料可以在到達時立即放入使用者的緩衝區中。 因此,它可以避免在呼叫recv或recvfrom函式時發生的複製操作。 如果在釋出接收緩衝區時資料已存在,則會立即將其複製到使用者的緩衝區中。

如果資料在應用程式未釋出接收緩衝區時到達,則網路將採用熟悉的同步操作方式。 也就是說,輸入資料在內部緩衝,直到應用程式發出接收呼叫,從而提供可以複製資料的緩衝區。 例外情況是應用程式使用setsockopt將接收緩衝區的大小設定為零。 在這種情況下,可靠的協議只允許在釋出應用程式緩衝區時接收資料,並且丟失不可靠協議上的資料。

在傳送端,應用程式使用WSASend或WSASendTo提供指向已填充緩衝區的指標,然後同意在網路消耗緩衝區內容之前不以任何方式干擾緩衝區。

重疊的傳送和接收呼叫立即返回。 返回值為零表示I / O操作立即完成,並且已經發生了相應的完成指示。 也就是說,已經發訊號通知了相關的事件物件,或者已經對完成例程進行了排隊,並且當呼叫執行緒進入可警告的等待狀態時將執行該事件物件。

SOCKET_ERROR的返回值加上錯誤程式碼WSA_IO_PENDING表示已成功啟動重疊操作,並且在消耗了傳送緩衝區或接收操作已完成時將提供後續指示。 但是,對於位元組流樣式的套接字,無論緩衝區是否已滿,每當傳入資料耗盡時都會發生完成指示。 任何其他錯誤程式碼表示重疊操作未成功啟動,並且沒有完成指示即將到來。

傳送和接收操作都可以重疊。 可以多次呼叫接收函式以釋出接收緩衝區以準備傳入資料,並且可以多次呼叫傳送函式以對要傳送的多個緩衝區進行排隊。 雖然應用程式可以依賴於以所提供的順序傳送的一系列重疊的傳送緩衝區,但是相應的完成指示可能以不同的順序發生。 同樣,在接收方,緩衝區可以按它們提供的順序填充,但完成指示可能以不同的順序發生。

在許多情況下,使用AcceptEx,ConnectEx,WSASend,WSARecv,TransmitFile和類似函式的Winsock重疊操作是可取消的。 但是,對於已取消未完成操作的套接字的繼續使用,行為未定義。 取消重疊操作後應呼叫closesocket函式。 因此,為了獲得最佳結果,不應直接取消I / O,而應呼叫closesocket函式來關閉套接字,最終將終止所有掛起的操作。

重疊I / O的延遲完成功能也可用於WSAIoctl,它是ioctlsocket的增強版本。

事件物件

引入重疊I / O需要一種機制,使應用程式能夠明確地將傳送和接收請求與其後續完成指示相關聯。 在Windows套接字2中,這是通過在Windows事件之後建模的事件物件來完成的。 Windows套接字事件物件是相當簡單的構造,可以建立和關閉,設定和清除,等待和輪詢。 它們的主要功能是應用程式阻止並等待一個或多個事件物件設定的能力。

應用程式使用WSACreateEvent獲取事件物件控制代碼,然後可以將其作為必需引數提供給傳送和接收呼叫的重疊版本(WSASend,WSASendTo,WSARecv,WSARecvFrom)。 首次建立時清除的事件物件由傳輸提供程式在關聯的重疊I / O操作完成(成功或有錯誤)時設定。 WSACreateEvent建立的每個事件物件都應該有一個匹配的WSACloseEvent來銷燬它。

WSAEventSelect中還使用事件物件將一個或多個FD_XXX網路事件與事件物件相關聯。 在使用事件物件的非同步通知中對此進行了描述。

在32位環境中,與事件物件相關的函式(包括WSACreateEvent,WSACloseEvent,WSASetEvent,WSAResetEvent和WSAWaitForMultipleEvents)使用相同的函式名稱直接對映到相應的本機Windows函式,但沒有WSA字首。

接收完成指示

有幾種方法可用於接收完成指示,從而為應用程式提供適當的靈活性。 其中包括:等待(或阻塞)事件物件,輪詢事件物件和套接字I / O完成例程。

阻止和等待完成指示

應用程式可以在等待使用WSAWaitForMultipleEvents函式設定一個或多個事件物件時阻塞。 在Windows實現中,程序或執行緒真正阻塞。 由於Windows Sockets 2事件物件是作為Windows事件實現的,因此本機Windows函式WaitForMultipleObjects也可用於此目的。 如果執行緒需要在套接字和非套接字事件上等待,這尤其有用。

輪詢完成指示

不想阻止的應用程式可以使用WSAGetOverlappedResult函式來輪詢與任何特定事件物件關聯的完成狀態。 此函式指示重疊操作是否已完成,如果已完成,則安排WSAGetLastError函式檢索重疊操作的錯誤狀態。

使用套接字I / O完成例程

用於啟動重疊I / O的函式(WSASend,WSASendTo,WSARecv,WSARecvFrom)都將lpCompletionRoutine作為可選的輸入引數。 這是指向成功啟動的重疊I / O操作完成(成功或其他)後呼叫的特定於應用程式的函式的指標。 完成例程遵循與Windows檔案I / O完成例程相同的規則。 也就是說,線上程處於可警告的等待狀態之前不會呼叫完成例程,例如在設定了FALERTABLE標誌的情況下呼叫函式WSAWaitForMultipleEvents時。 對特定重疊I / O請求使用完成例程選項的應用程式可能不會對同一重疊I / O請求使用WSAGetOverlappedResult的wait選項。

傳輸允許應用程式從套接字I / O完成例程的上下文中呼叫傳送和接收操作,並保證對於給定的套接字,I / O完成例程將不會巢狀。 這允許時間敏感的資料傳輸完全在搶佔上下文中發生。

重疊完井指示機制綜述

用於給定重疊操作的特定重疊I / O完成指示由應用程式是否提供指向完成函式的指標,是否引用WSAOVERLAPPED結構以及WSOAVERLAPPED結構中的hEvent成員的值來確定( 如果提供)。 下表總結了重疊套接字的完成語義,並顯示了lpOverlapped,hEvent和lpCompletionRoutine的各種組合:

lpOverlapped hEvent lpCompletionRoutine Completion indication
NULL Not applicable Ignored 操作同步完成。 它表現得好像是一個非重疊的套接字。
!NULL NULL NULL 操作完成重疊,但沒有Windows Sockets 2支援的完成機制。 在這種情況下,可以使用完成埠機制(如果支援)。 否則,沒有完成通知。
!NULL !NULL NULL 操作完成重疊,通過訊號事件物件進行通知。
!NULL Ignored !NULL 操作完成重疊,通過排程完成例程進行通知。

使用事件物件的非同步通知

提供WSAEventSelect和WSAEnumNetworkEvents函式以適應諸如守護程式和沒有使用者介面的服務之類的應用程式(因此不使用Windows控制代碼)。 WSAEventSelect函式的行為與WSAAsyncSelect函式完全相同。 但是,不是在發生FD_XXX網路事件(例如,FD_READ和FD_WRITE)時傳送Windows訊息,而是設定應用程式指定的事件物件。

此外,服務提供商還記住發生特定FD_XXX網路事件的事實。 應用程式可以呼叫WSAEnumNetworkEvents將網路事件儲存器的當前內容複製到應用程式提供的緩衝區,並自動清除網路事件儲存器。 如果需要,應用程式還可以指定與網路事件儲存器一起清除的特定事件物件。

相關推薦

關於Winsock重疊I / O事件物件

Windows套接字2支援重疊I / O,所有傳輸提供程式都支援此功能。 重疊I / O遵循Windows中建立的模型,可以在使用套接字函式建立的套接字上執行,也可以使用WSASocket函式建立的套接字執行,並在dwFlags引數中設定WSA_FLAG_OVERLAPPED

I/O模型同步I/O非同步I/O,阻塞I/O非阻塞I/O

同步(synchronous) IO和非同步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分別是什麼,到底有什麼區別? 這個問題其實不同的人給出的答案都可能不同,在大部分的博文中(包括WIKI在內),我們很可能

安裝SEP時報Error 997重疊I/O操作在進行中

安裝SEP的時候可能遇到報錯:error 997. overlapped i/o operation is in progress 原因: Per Microsoft's blog, patch KB2918614 appears to have caused ins

虛擬機器報錯Unable to open kernel device "\\.\VMCIDev\VMX": 重疊 I/O 操作在進行中

  今天啟動虛擬機器突然出現: Unable to open kernel device "\\.\VMCIDev\VMX": 重疊 I/O 操作在進行中. Did you reboot after installing VMware Workstation? 這樣的報錯,

Java NIO淺析I/O模型

問題 區別 ror borde ket .cn dex selector 以及 學習Java的同學註意了!!! 學習過程中遇到什麽問題或者想獲取學習資源的話,歡迎加入Java學習交流群:618528494 我們一起學Java!   也許很多朋友在學習NIO的時候都會

CPU的端口映射I/O內存映射I/O

修改 繼續 進行 代碼 帶寬 中斷控制 讀寫操作 組成 地址 CPU在訪問內存時,通過數據總線和地址總線和內存交換信息,進行讀寫操作,這是內存映射I/O。 而當CPU訪問外接設備時,可通過內存映射和端口映射兩種方式進行I/O操作,通過內存映射訪問設備

SOCKET重疊I/O模型

offset 否則 其中 tran internal 如果 要求 定義 ber 1重疊模型的優點1可以運行在支持Winsock2的所有Windows平臺,而不像完成端口只支持NT系統2比起阻塞,select,WSAAsyncSelect以及WSAEventSelect等模型

Java筆記I/O

對象 輸入流 isa not 指定 printf compare turn 文件 一、基礎知識 Java通過流實現I/O,流是一種可以產生或使用信息的抽象。 Java定義了兩種類型的流: 字節流:處理字節的輸入和輸出,例如讀寫二進制數據。 字符流:處理字符的輸入和輸出。

第四章標準I/O管道

I/O 重定向 管道 筆記整體起始時間:2018年4月2日18:55:25 本章內容 三種I/O設備 把I/O重定向至文件 使用管道 標準輸入和輸出 程序:指令+數據 讀入數據:Input

linux初級學習筆記九linux I/O管理,重定向及管道!(視頻序號04_3)

font 運算 bsp 輸出 指令 所有 inittab tput bin 本節學習的命令:tr,tee,wc 本節學習的技能:       計算機的組成       I/O管理及重定向      管道的使用   知識點九:管理及IO重定向(4_3) 計算機組成:  

Linux學習第五節課-標準I/O管道

定向 描述 命令 終端 NPU 提示 err 輸出數據 所有 Linux學習第五節課------------------------------------

標準I/O管道

eas 命令 git 文件 .sh user 輸出 一行 源碼安裝 一部分:標準I/O和管道 1:Linux給程序提供三種I/O設備 ?標準輸入(STDIN)-0 默認接受來自鍵盤的輸入 ?標準輸出(STDOUT)-1 默認輸出到終端窗口 ?標準錯誤(STDERR)-2

Linux的標準I/O管道

導入 結果 鍵盤 nbsp tle pan 圖片 cto 刪除字符 標準輸入輸出與管道 1、標準輸入和輸出 程序:指令+數據 指令:計算、加減乘除 數據:輸

Windows系統編程之異步I/O完成端口

tip let 用處 thread 之前 pin san 隊列 int Windows系統編程之異步I/O和完成端口【作者】北極星2003【來源】看雪技術論壇(bbs.pediy.com) 【時間】2006年7月1日 一、 同步I/O和異步I/O 在介紹這部分內容之前

靈活使用標籤的data自定義屬性事件物件

如果需要動態的給每一個標籤新增一樣的事件,且只有對應的內容改變,則可以通過data事先定義好要用的資料,然後通過事件物件獲取,data自定義屬性可以是一個字串或者是一個物件 形如:    data-address=“中華人民共和國”   data-sta

java I/ONI/O 詳解

目錄 I/O概述 字元流 位元組流 理解I/O超類結構 FileInputStream詳解  FileOutputStream詳解 File類 新I/O Java NIO: Channels and Buffers Channels &nbs

c51 函式庫函式 STDIO.H一般I/O函式

  c51 函式 (3)     3.2 STDIO.H:一般I/O函式     在標頭檔案中增加include <stdio.h>     C51編譯器包含字元I/O函式,它們通過處理器的序列介面操作,為支援其它

文件I/O標準I/O函數

size seek putchar 文件指針 安全 二進制 fputs exit 函數 讀取/寫入 相對於文件而言 輸入/輸出 相對於程序/內存而言 一切皆文件,鍵盤、顯示屏也是文件,只不過是特殊的標準文件; 標準文件:標準輸入、標準輸出、標準錯誤;---->對應的

C標準庫I/OLinux檔案I/O

I/O分類:     有兩種I/O,一是檔案I/O,而我們c語言的封裝叫標準I/O,他們有什麼區別那?顯然標準I/O是基於檔案I/O的,標準IO呼叫了檔案IO,也優化了檔案IO,例如引入快取機制。     所以C標準

過濾器練習獲取指定目錄以及子目錄下的檔案(副檔名為.java)使用遞迴File物件過濾器!

package cn.itcast.day01_03; import java.io.File; import java.io.FileFilter; /* * 過濾器練習:獲取指定目錄以及子目錄下的檔案(副檔名為.java):使用遞迴和File物件過濾器! */ public cl