轉載自:
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
只能獲得
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 中傳遞進來的緩衝區的字節長度。要注意的是,某些調用可能只使用了輸入或輸出參數,而另一些調用兩類參數都會用到。,對應於實際返回的字節數。
lpOverlapped 和 lpCompletionRoutine ,在隨重疊 I/O 調用這個函數時使用。