getsockopt、setsocketopt、ioctlsocket和WSAIoctl 詳解

轉載自:

http://www.360doc.com/content/13/0115/11/10977253_260278513.shtml

套接字選項和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 
只能獲得 

確定指定的AppleTalk名字和指定地址綁定在一起 

SO_DEREGISTER_NAME , SO_REMOVE_NAME 
WSH_REGISTER_NAME 
只能設置 

從網絡中撤消對指定名字的註冊 

SO_LOOKUP_MYZONE ,

SO_GETMYZONE 
字符 
只能獲取 

返回網絡上的默認網區 

SO_LOOKUP_NAME 
W SH_LOOKUP_NAME 
只能獲取 

查找指定的NBP名字,並返回相符的名字及N B P信息字元組 

SO_LOOKUP_ZONES ,

SO_GETZONELIST 
WSH_LOOKUP_ZONES 
只能獲取 

返回來自Internet網區列表的區名 

SO_LOOKUP_ZONES_ON_ADAPTER , SO_GETLOCALZONES 
WSH_LOOKUP_ZONES 
只能獲取 

爲指定的適配器名返回一個區名列表 

SO_LOOKUP_NETDEF_ON_ADAPTER , SO_GETNETINFO 
WSH_LOOKUP_NETDEF_ON_ADAPTE 
只能設置 

爲指定網絡返回種子值,以及默

認網區



SO_PAP_GET_SERVER_STATUS 
WSH_PAP_GET_SERVER_STATUS 
只能獲取 

自指定服務器返回PA P狀態



SO_PAP_PR IME_READ 
char [] 
只能設置 

這個調用會在一個PA P連接上填充一次讀取操作,以便發送者能實際地發出數據 

SO_PAP_S ET_SERV ER_STTUS 
char [] 
只能設置 

假如另一個客戶機請求狀態,則設置要發送出去的狀態



SO_REGISTER_NAME 
char [] 
只能設置 

在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 中傳遞進來的緩衝區的字節長度。要注意的是,某些調用可能只使用了輸入或輸出參數,而另一些調用兩類參數都會用到。,對應於實際返回的字節數。

 lpOverlapped 和 lpCompletionRoutine ,在隨重疊 I/O 調用這個函數時使用。​

發佈了23 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章