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