WSAIoctl 函数详解
套接字選項和I/O控制命令
?? 套接字一旦建立,通過套接字選項和I/O控制命令對各種屬性進行操作,便可對套接字的行為產生影響。有的選項只用于信息的返回,而有的選項則可在應用程序中影響套接字的行為。I / O控制命令肯定會對套接字的行為產生影響。
?? 下面著重討論四個Winsock函數:getsockopt、setsocketopt、ioctlsocket和WSAIoctl 。每個函數都有大量命令。這些I/O控制命令和選項大多定義在Winsock.h或Winsock2.h內,具體取決于它們到底從屬于Winsock 1,還是從屬于Winsock 2。但是,也有少數幾個選項是Microsoft提供者或某種傳輸協議所特有的。微軟特有的一些擴展定義在Winsock.h和Mswsock.h 這兩個頭文件內。而傳輸提供者擴展定義在與其協議對應的頭文件內。針對那些傳輸特有選項,我們將隨選項一道,指明正確的頭文件是什么。要注意的是,若應用程序使用了微軟特有的擴展,那么必須同Mswock.lib建立鏈接。
?? 套接字選項
?? 對getsocketopt(獲得套接字選項)函數來說,它的常見用法是獲得與指定套接字相關的信息。
??? 其原型如下:
??? int getsocketopt(SOCKKET s,int level,int optname,char FAR* optval,int optlen)
??? s 指定的是一個套接字,我們打算在這個套接字上執行指定的選項。對你打算使用的具體協議來說,這個套接必須是有效的。大多數選項都是一種特定的協議和套接字類型專有的,而其他選項適用于所有類型的套接字(特別是第二個參數level)。
??? optname參數是我們在此真正感興趣的選項。 這些選項名均在 Winsock頭文件內定義的常數值。最常見的與協議無關選項(比如和SOL_SOCKET級別關聯在一起的選項)是在Winsock.h和 Winsock2.h這兩個頭文件中定義的。對于每種特定的協議來說,它們都有自己的頭文件,定義了與之對應的特定選項。
?? 最后,optval和 optlen參數是兩個變量,用于返回目標選項的值 。大多數情況下,選項值都是一個整數(但也不是絕對的)
.
?? setsocketopt函數用于在一個套接字級別或由協議決定的級別上設置套接字選項。它的定義如下:
?? int setsocketopt(SOCKKET s,int level,int optname,const char FAR* optval,int optlen)
?? 它的參數和getsocketopt函數的參數相同,例外的是我們以optval和optlen參數的形式,將值傳遞進去。這些值是為指定的選項設定的。和 getsocketopt函數一樣,optval大多數時候都是一個整數,但也并非總是如此。正式編程的時候,應查詢對每個選項的說明,了解到底該將什么作為選值傳遞進去。調用getsocketopt或setsocketopt時,最常見的錯誤是試圖獲得一個套接字的信息,但那個套接字的基層協議卻不具備某種指定的特征(或選項)。例如,類型為SOCK_STREAM的一個套接字本身是不能對數據進行廣播操作的;因此,若試圖設置或獲取 SO_BROADCAST選項,便會造成WSAENOPRORTOOPT錯誤。
SOL_SOCKET選項級別
介紹可根據套接字本身的特征,返回信息的一些套接字選項,但這些信息并非那個
套接字的基層協議所特有的(與它無關).
選項級別值?
選項值?
類型獲取 / 設置?
Winsock 版本?
說明?
SO_ACCEPTCONN?
布爾值?
只能獲取?
1 +?
如為TRUE(真),表明套接字處于監聽模式?
SO_BROADCAST?
布爾值?
兩種均可?
1 +?
如為TRUE,表明套接字已配置成對廣播消息進行發送?
SO_CONNECT_TIME?
整數?
只能獲取?
1 +?
返回套接字建立連接的時間,以秒為單位?
SO_DEBUG?
布爾值?
兩種均可?
1 +?
如果是TRUE,就允許調試輸出?
SO_DONTLINGER?
布爾值?
兩種均可?
1 +?
如果是T R U E,則禁用SO_LINGER?
SO_DONTROUTE?
布爾值?
兩種均可?
1 +?
如果是T R U E,便直接向網絡接口發送消息,毋需查詢路由表?
SO_ERROR?
布爾值?
只能獲得?
1 +?
返回錯誤狀態?
SO_EXCLUSIVEADDRUSE?
布爾值?
兩種均可?
2 +?
如果是TRUE,套接字綁定的那個本地端口就不能重新被另一個進程使用?
SO_KEEPALIVE?
布爾值?
兩種均可?
1 +?
如果是T R U E,套接字就會進行配置,在會話過程中發送“保持活動”消息?
SO_LINGER?
st ruct linger?
兩種均可?
1 +?
設置或獲取當前的拖延?
SO_MAX_MSG_SIZE?
無符號整數?
只能獲得?
2 +?
對一個面向消息的套接字來說,一條消息的最大長度?
SO_OOBINLINE?
布爾值?
兩種均可?
1 +?
如果是T R U E,帶外數據就會在普通數據流中返回?
SO_PROTOCOL_INF O?
WSAPROTOCOL_INFO?
只能獲得?
2 +?
套接字綁定的那種協議的特征?
SO_RCVBUF?
整數?
兩種均可?
1 +?
面向接收操作,為每個套接字分別獲取或設置緩沖區長度?
SO_REUSEADDR?
布爾值?
兩種均可?
1 +?
如果是TRUE,套接字就可與一個正由其他套接字使用的地址綁定到一起,或與處在TIME_WAIT狀態的地址綁定到一起?
SO_SNDBUF?
布爾值?
兩種均可?
1 +?
如果是TRUE(非零值),意味著套接字被配置成可進行廣播消息的發送?
SO_TYPE?
整數?
只能獲得?
1 +?
返回指定套接字的類型(如SOCK_DGRAM和SOCK_STREAM等)?
SO_SNDTIMEO?
整數?
兩種均可?
1 +?
獲取或設置套接字上的數據發送超時時間(以毫秒為單位)?
SO_RCVTIMEO?
整數?
兩種均可?
1 +?
獲取或設置與套接字上數據接收對應的超時時間值(以毫
秒為單位)?
SO_UPDATE_ACCEPT_CONTEXT?
S O C K E T?
兩種均可?
1 +?
獲取或設置與套接字上的數據接收對應的超時值(以毫秒計)?
SOL_APPLETALK選項級別
下述選項均為AppleTalk協議之專用套接字選項,只能用于通過socket或WSASocket函數
創建的套接字(同時設置AF_APPLETALK標志)。這里列出的大多數選項都與A ppleTalk名字
的設置或獲取有關。
選項級別值?
選項值?
類型獲取 / 設置?
Winsock 版本?
說明?
SO_CONFIRM_NAM?
WSH_NBP_TUPLE?
只能獲得?
1?
確定指定的AppleTalk名字和指定地址綁定在一起?
SO_DEREGISTER_NAME , SO_REMOVE_NAME?
WSH_REGISTER_NAME?
只能設置?
1?
從網絡中撤消對指定名字的注冊?
SO_LOOKUP_MYZONE ,
SO_GETMYZONE?
字符?
只能獲取?
1?
返回網絡上的默認網區?
SO_LOOKUP_NAME?
W SH_LOOKUP_NAME?
只能獲取?
1?
查找指定的NBP名字,并返回相符的名字及N B P信息字元組?
SO_LOOKUP_ZONES ,
SO_GETZONELIST?
WSH_LOOKUP_ZONES?
只能獲取?
1?
返回來自Internet網區列表的區名?
SO_LOOKUP_ZONES_ON_ADAPTER , SO_GETLOCALZONES?
WSH_LOOKUP_ZONES?
只能獲取?
1?
為指定的適配器名返回一個區名列表?
SO_LOOKUP_NETDEF_ON_ADAPTER , SO_GETNETINFO?
WSH_LOOKUP_NETDEF_ON_ADAPTE?
只能設置?
1?
為指定網絡返回種子值,以及默
認網區
SO_PAP_GET_SERVER_STATUS?
WSH_PAP_GET_SERVER_STATUS?
只能獲取?
1?
自指定服務器返回PA P狀態
SO_PAP_PR IME_READ?
char []?
只能設置?
1?
這個調用會在一個PA P連接上填充一次讀取操作,以便發送者能實際地發出數據?
SO_PAP_S ET_SERV ER_STTUS?
char []?
只能設置?
1?
假如另一個客戶機請求狀態,則設置要發送出去的狀態
SO_REGISTER_NAME?
char []?
只能設置?
1?
在AppleTalk網絡上注冊指定的名字
SOL_IRLMP選項級別
SOL_IRLMP 級別與IrDA(Infrared Data Association,紅外線數據聯盟)協議有著密切的聯系,其地址家族為AF_IRDA。使用IrDA套接字選項時,要記住的一個要點在于,在不同平臺上,紅外線套接字的具體實施方式是有所區別的。由于Windows CE是最早支持紅外線通信的一個平臺,所以沒有包括后來在Windows 98和Windows 2000中引入的一些新選項。
選項級別值?
選項值?
類型獲取 / 設置?
Winsock 版本?
說明?
IRLMP_9WIRE_MODE?
布爾值?
兩種均可?
1 +?
獲取或設置IP頭內的IP選項?
IRLMP_ENUMDEVICES?
DEVICELIST?
只能獲取?
1 +?
針對范圍內具有紅外線通信能力的設備,返回一個IrDA設備ID列表?
IRLMP_EXECLUSIVE_MODE?
布爾值?
兩種均可?
1 +?
如果是TRUE,表明套接字連接處于“獨占”模式?
IRLMP_IAS_QUERY?
IAS-QUERY?
只能獲取?
1 +?
在指定服務上查詢IAS,并查詢與其屬性對應的類名?
IRLMP_IAS_SET?
IAS-QUERY?
只能獲取?
1 +?
為指定的類名和屬性設置一個屬性值?
IRLMP_IRLPT_MODE?
布爾值?
兩種均可?
1 +?
若為T R U E,套接字就會配置成與具有I R能力的打印機通信?
IRLMP_SEND_PDU_LEN?
整數?
只能獲得?
1 +?
取得最大的PDU長度?
IPPROTO_IP選項級
IPPROTO_IP這一級的套接字選項與I P協議存在密切聯系,比如可用它們IP頭內的特定字
段,以及向IP多播組增添一個套接字等等。許多這樣的選項都聲明于Winsock.h和Winsock2.h
這兩個頭文件內,而且采用了不同的值。要注意的是,假如裝載的是Winsock1,那么必須包
括正確的頭文件,同時建立與Wsock32.lib 函數庫的鏈接關系。若裝載的是Winsock 2,那么情況也是類似的,除了將Winsock 2的頭文件包括進來外,還要建立與Ws2_32.lib的鏈接關系。在多播通信環境中,這一點尤其重要,因為兩個版本的Wi n s o c k均支持多播通信。除WindowsCE的早期版本之外,其他所有Win32平臺都提供了對多播通信的支持。而Windows CE自2.1版之后,也開始提供了這方面的支持。
選項級別值?
選項值?
類型獲取 / 設置?
Winsock 版本?
說明?
IP_OPTIONS?
char []?
兩者均可?
1 +?
設置或獲取IP頭內的IP選項?
IP_HDRINCL?
布爾值?
兩種均可?
2 +?
如果是TRUE,IP頭就會隨即將發送的數據一起提交,并從 讀取的數據中返回?
IP_TOS?
整數?
兩種均可?
1 +?
IP服務類型?
IP_TTL?
整數?
兩種均可?
1 +?
IP協議的“存在時間”(TTL)參數
IP_MULTICAST_IF?
無符號長整型?
兩種均可?
1 +?
獲取或設置打算從它上面發出多播數據的本地接口?
IP_MULTICAST_TTL?
整數?
兩種均可?
1 +?
為套接字獲取或設置多播數據包的存在時間?
IP_MULTICAST_LOOP?
布爾值?
兩種均可?
1 +?
如果是TRUE,發至多播地址的數據將原封不動地“反射”
或“反彈”回套接字的進入緩沖區?
IP_ADD_MEMBERSHIP?
struc ip_mreq?
只能設置?
1 +?
在指定的IP組內為套接字賦予成員資格?
IP_DROP_MEMBERSHIP?
struc ip_mreq?
只能設置?
1 +?
將套接字從指定的IP組內刪去(撤消成員資格)?
IP_DONTFRAGMENT?
布爾值?
兩種均可?
1 +?
如果是T R U E,就不對I P數據報進行分段?
IPPROTO_TCP選項級別
僅有一個選項從屬于IPPROTO_TCP級別。該選項只適用于流式套接字(SOCK_STREAM),其地址家族為AF_INET。這個選項可用在所有Winsock版本上,并得到了所有Win32平臺的支持,包括Windows CE。
TCP_NODELAY 布爾值??? 兩者均可???? 1 +?? 若為TRUE,就會在套接字上禁用Nagle算法
NSPROTO_IPX選項級別
選項級別值?
選項值?
類型獲取 / 設置?
Winsock 版本?
說明?
IPX_PTYPE?
整數?
兩種均可?
1 +?
獲取或設置IPX包的類型?
IPX_FILTERPTYPE?
整數?
兩種均可?
1 +?
獲取或設置準備過濾的I P X包之類型?
IPX_STOPFILTERPTYPE?
整數?
只能設置?
1 +?
刪除為指定IPX包設置的過濾器?
IPX_DSTYPE?
整數?
兩種均可?
1 +?
獲取或設置SPX頭中的數據流字段值?
IPX_EXTENDED_ADDRESS?
布爾值?
兩種均可?
1 +?
如果是TRUE,便允許對IPX包進行擴展定址?
IPX_RECVHDR?
布爾值?
兩種均可?
1 +?
如果是TRUE,就隨接收調用一起,返回IPX頭?
IPX_MAXSIZE?
整數?
只能獲取?
1 +?
返回IPX數據報的最大長度?
IPX_ADDRESS?
IPX_ADDRESS_D ATA?
只能獲取?
1 +?
返回具備IPX能力之適配器的有關信息?
IPX_GETNE TINFO?
IPX_NETNUM_D ATA?
只能獲取?
1 +?
返回與一個指定IPX網絡編號有關的信息?
IPX_GETNETINFO_NORIP?
IPX_ADDRESS_DATA?
兩種均可?
1 +?
如果是TRUE,就不會對IP數據報進行分段?
IPX_SPXGETCONNECTIONSTAT U S?
IPX_SPXCONNSTATUS_DATA?
只能獲取?
1 +?
返回與一個已建立連接的SPX套接字有關的信息?
IPX_ADDRESS_NOTIFY?
I PX_ADDRESS_DATA?
只能獲取?
1 +?
若IPX適配器的狀態發生改變,則發出異步通知?
IPX_MAX_ADAPTER_NUM?
整數?
只能獲取?
1 +?
返回存在的IPX適配器個數?
IPX_RERIPNETNUMBER?
IPX_NETNUM_DATA?
只能獲取?
1 +?
返回一個網絡編號的相關信息?
IPX_RECEIVE_BROADCAST?
布爾值?
只能設置?
1 +?
如果是TRUE,就不接收IPX廣播包?
IPX_IMMEDITESPXZCK?
布爾值?
兩種均可?
1 +?
如果是TRUE,就不在SPX連接上延遲發送ACK?
I OCTLSOCKET和WSAIOCTL
一系列套接字 I/O 控制函數用于在套接字之上,控制 I/O 的行為,同時獲取與那個套接字上
進行的 I/O 操作有關的信息。
其中,第一個函數是 ioctlsocket ,起源于 Winsock 1 規范,聲明如下:
int olctlsocket(SOCKET s,long cmd,u_long FAR* argp)
其中,參數 s 指定的是要在上面采取 I/O 操作的套接字描述符,而 cmd 是一個預定義的標志,
用于打算執行的 I/O 控制命令。最后一個參數 argp 對應的是一個指針,指向與命令密切相關的一個變量。描述好每個命令之后,再給出要求變量的類型。
?? Winsock 2 引入了一個新的 ioctl 函數,增添了數量多得多的新選項。首先,它將單個 argp 參數分解成了一系列輸入參數,用于容納傳遞到函數內部的值;同時提供一系列輸出參數,用于容納自調用返回的數據。此外,
函數調用可使用重疊 I/O 。這個新函數便是 WSAIoctl ,它的定義如下:
int WSAIoctl(SOCKET s,DWORD dwIoControlCode,LPVOID lpvInBuffer,DWORD cbInBuffer,
LPVOID lpvOutBuffer,DWORD cbOutBuffer,LPDWORD lpcbBytesReturned,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
頭兩個參數與 ioctlsocket 的相同。另兩個參數( lpvInBuffer 和 cbInBuffer )則對輸入參數
進行了描述。其中, lpvInBuffer 參數是一個指針,指向傳遞進入的值,而 cbInBufer 指定的是數據的多少,以字節為單位。類似地, lpvOutBuffer 和 cbOutBuffer 用于自調用返回的任何數據。 l pvOutBuffer 參數指向的是一個數據緩沖區,其中放置了返回的所有信息。而 cbOutBuffer 參數對應的是在 lpvOutBuffer 中傳遞進來的緩沖區的字節長度。要注意的是,某些調用可能只使用了輸入或輸出參數,而另一些調用兩類參數都會用到。第七個參數是 lpcbBytesReturned ,對應于實際返回的字節數。最后兩個參數是 lpOverlapped 和 lpCompletionRoutine ,在隨重疊 I/O 調用這個函數時使用。
總結
以上是生活随笔為你收集整理的WSAIoctl 函数详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WinSock2编程之打造完整的SOCK
- 下一篇: IOCP 浅析与实例