有很多方法來獲取和設置影響套接口的選項:
這兩個函數僅用于套接口。
#include <sys/socket.h>int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t *optlen);返回值:0——成功,-1——出錯
其中,
sockfd必須指向一個打開的套接口描述字;
level(級別)指定系統中解釋選項的代碼:或為通用套接口代碼,或為某個特定于協議的代碼(例如ipv4、IPv6、TCP或SCTP)。
optval是一個指向變量(*optval)的指針,setsockopt從*optval中取得選項待設置的新值,getsockopt則把已獲取的選項當前值存放到*optval中。
optlen指定*optval的大小,它對于setsockopt是一個值參數,對于getsockopt是一個值-結果參數。
套接口選項粗分為兩大基本類型:
(1)標志選項:開啟或禁止某個特性的二元選項。
(2)值選項:取得并返回我們可以設置或檢查的特定值的選項。
*optval的值為0表示禁止選項,不為0表示開啟選項。
fcntl函數提供了與網絡編程相關的如下特性:
#include <fcntl.h>int fcntl(int fd, int cmd, ... /* int arg */);返回值:依賴于cmd參數——成功,-1——出錯
每種描述字(包括套接口描述字)都有一組由F_GETFL命令獲取或由F_SETFL命令設置的文件標志。其中影響套接口描述字的兩個標志是:
O_NONBLOCK 非阻塞I/O
O_ASYNC 信號驅動I/O
注意
設置某個文件狀態標志的唯一正確的方法是:先取得當前標志,與新標志邏輯或后再設置標志。例如,使用fcntl開啟非阻塞I/O的典型代碼是:
int flags;if( (flags = fcntl(fd, F_GETFL, 0)) < 0) err_sys("F_GETFL error");flags |= O_NONBLOCK;if(fcntl(fd, F_SETFL, flags) < 0) err_sys("F_SETFL error");
信號SIGIO和SIGURG與其他信號的不同之處在于,這兩個信號僅在已使用F_SETOWN命令給相關套接口指派了屬主后才會產生。
F_SETOWN命令的整數類型arg參數既可以是一個正整數,指出接收信號的進程ID,也可以是一個負整數,其絕對值指出接收信號的進程組ID。
F_GETOWN命令把套接口屬主作為fcntl函數的返回值返回,它既可以是進程ID(一個正的返回值),也可以是進程組ID(一個除-1以外的負值)。
指定接收信號的套接口屬主為一個進程或一個進程組的差別在于:前者僅導致單個進程接收信號,而后者則導致整個進程組中的所有進程(也許不止一個進程)接收信號。
使用socket函數新創建的套接口并沒有屬主。然而如果一個新的套接口是從一個監聽套接口創建來的,那么套接口屬主將由已連接套接口從監聽套接口繼承而來。
SO_KEEPALIVE
給一個TCP套接口設置保持存活(keep-alive)選項后,如果2小時內在該套接口的任一方向上都沒有數據交換,TCP就自動給對端發送一個保持存活探測分節(keep-alive PRobe)。這是一個對端必須響應的分節。
本選項的目的是檢測對端主機是否崩潰或變得不可達。
本選項一般由服務器使用,不過客戶也可以使用。
服務器使用本選項是因為它們花大部分時間阻塞在等待穿越TCP連接的輸入上,也就是說在等待客戶的請求。然而如果客戶主機連接掉線、電源掉電或系統崩潰,服務器進程將永遠不會知道,并將繼續等待永遠不會到達的輸入。我們稱這種情況為半開連接(half-open connection)。保持存活選項將檢測出這些半開連接并終止它們。
SO_RCVBUF、SO_SNDBUF
每個TCP套接口和SCTP套接口都有一個發送緩沖區和一個接收緩沖區,每個UDP套接口都有一個接收緩沖區。SO_SNDBUF和SO_RCVBUF套接口選項允許我們改變這些緩沖區的大小。對于客戶,SO_RCVBUF選項必須在調用connect之前設置;對于服務器,SO_RCVBUF選項必須在調用listen之前給監聽套接口設置。
SO_REUSEADDR
SO_REUSEADDR套接口選項為以下四個不同的目的提供服務:
(1)SO_REUSEADDR允許啟動一個監聽服務器并捆綁其眾所周知端口,即使以前建立的將該端口用作它們的本地端口的連接仍存在。
(2)SO_REUSEADDR允許在同一端口上啟動對同一服務器的多個實例,只要每個實例捆綁一個不同的本地IP地址即可。
(3)SO_REUSEADDR允許單個進程捆綁同一端口到多個套接字上,只要每次捆綁指定不同的本地IP地址即可。
(4)SO_REUSEADDR允許完全重復的綁定:當一個IP地址和端口已綁定到某個套接口上時,如果傳輸協議支持,同樣的IP地址和端口可以捆綁到另一個套接口上。一般來說,本特性只支持UDP套接口。
所有TCP服務器都應指定SO_REUSEADDR選項。
新聞熱點
疑難解答