有不少方法來獲取和設置影響套接口的選項:編程
這兩個函數僅用於套接口。服務器
#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必須指向一個打開的套接口描述字;socket
level(級別)指定系統中解釋選項的代碼:或爲通用套接口代碼,或爲某個特定於協議的代碼(例如IPv四、IPv六、TCP或SCTP)。函數
optval是一個指向變量(*optval)的指針,setsockopt從*optval中取得選項待設置的新值,getsockopt則把已獲取的選項當前值存放到*optval中。spa
optlen指定*optval的大小,它對於setsockopt是一個值參數,對於getsockopt是一個值-結果參數。指針
套接口選項粗分爲兩大基本類型:code
(1)標誌選項:開啓或禁止某個特性的二元選項。blog
(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選項。