UNIX網絡編程讀書筆記:套接口選項

紅心概述

有不少方法來獲取和設置影響套接口的選項:編程

  • getsockopt和setsockopt函數
  • fcntl函數
  • ioctl函數

紅心getsockopt和setsockopt函數

這兩個函數僅用於套接口。服務器

#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函數

fcntl函數提供了與網絡編程相關的以下特性:

  1. 非阻塞I/O。經過使用F_SETFL命令設置O_NONBLOCK文件狀態標誌,咱們能夠把一個套接口設置爲非阻塞型。
  2. 信號驅動I/O。經過使用F_SETFL命令設置O_ASYNC文件狀態標誌,咱們能夠把一個套接口設置成一旦其狀態發生變化,內核就產生一個SIGIO信號。
  3. F_SETOWN命令容許咱們指定用於接收SIGIO和SIGURG信號的套接口屬主(進程ID或進程組ID)。其中SIGIO信號是套接口被設置爲信號驅動I/O型後產生的,SIGURG信號是在新的帶外數據到達套接口時產生的。F_GETOWN命令返回套接口的當前屬主。
#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的獨特之處

信號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選項。

相關文章
相關標籤/搜索