1. 套接字選項函數原型:
#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); ret-成功返回0 失敗返回-1
2. 通用套接字選項:
(1) SO_BROADCAST:
本選項開啟或禁止進程發送廣播消息的能力;只有數據報套接字支持廣播,並且還必須是在支持廣播消息的網絡上;
(2) SO_DEBUG:
本選項僅由TCP支持。當給一個TCP套接字開啟本選項,內核將為TCP在該套接字和接收的所有分組保留詳細跟蹤信息。這些信息保存在內核的某個環形緩沖區中,並可以使用trpt程序進行檢查;
(3) SO_DONTROUTE:
本選項規定外出的分組將繞過底層協議的正常路由機制,以強制將分組從特定接口送出;
(4) SO_ERROR:
當一個套接字上發生錯誤時,源自Berkeley的內核中的協議模塊將該套接字的名為so_error的變量設為標准的Unix_Exxx值中的一個,我們稱它為該套接字的待處理錯誤。內核能夠以下面的兩種方式之一立即通知進程這個錯誤;
--如果進程阻塞在對該套接字的select調用上,那么無論是檢查可讀條件還是可寫條件,select均返回並設置其中一個或所有兩個條件;
--如果進程使用信號驅動式I/O模型,那就給進程或者進程產生一個SIGIO信號;
進程然后可以通過訪問SO_ERROR套接字選項后去so_error值。由getsockopt返回的整數值就是該套接字的待處理錯誤。so_error隨后由內核復位為0;
(5) SO_KEEPALIVE:
給一個tcp套接字設置保持存活選項后,如果2小時內在該套接字的任一方向上沒有數據交換,tcp就自動給對端發送一個保持存活探測分節。這是一個對端必須響應的tcp分節,它會導致以下三種情況之一;
--對端以期望的ack響應。應用進程得不到通知。在又經過無動靜的2小時之后,tcp將發出另外一個探測分節;
--對端以rst響應,它告知本端tcp,對端已崩潰且重新啟動。該套接字的待處理錯誤被置ECONNRESET,套接字本身則被關閉;
--對端對保持存活探測分節沒有任何響應。源自Berkeley的tcp將另外發送8個探測分節,兩兩相隔75秒,視圖得到一個響應。如果探測分節沒有響應,該套接字的處理錯誤被置為ETIMEOUT;
(6) SO_LINGER:
--shutdown, SHUT_RD: 在套接字上不能再發出接收請求,進程仍可以網套接字發送時數據,套接字接收緩沖區中所有數據被丟棄;再接收到任何的tcp丟棄;對套接字發送緩沖區沒有任何影響;
--shutdown, SHUT_WR: 在套接字上不能再發出發送請求,進程仍可以從套接字接收數據,套接字發送緩沖區中的內容被發送到對端,后跟正常的tcp連接終止序列,即發送fin,對套接字接收緩沖區沒有任何影響;
--close,l_onoff=0: 在套接字上不能再發出發送或者接收請求;套接字發送緩沖區中的內容被發送到對端,如果描述符引用計數變為0,在發送完發送緩沖區中的數據后,跟以正常的tcp連接終止序列,套接字接收緩沖區中的內容被丟棄;
--close,l_onoff = 1, l_linger = 0: 在套接字上不能再發出發送或接收請求;如果描述符引用計數變為0,rst被發送到對端;連接狀態被置為CLOSED(沒有TIME_WAIT);套接字發送緩沖區和套接字接收緩沖區中的數據被丟棄;
--close, l_onoff = 1, l_linger != 0: 在套接字上不能再發出發送或者接收請求;套接字發送緩沖區的數據被發送到對端;如果描述符引用計數為0,在發送完緩沖區中的數據后,跟以正常的tcp連接終止序列;套接字接收緩沖區的數據被丟棄;如果在連接變為CLOSED狀態前延滯時間到,那么colose返回EWOULDBLOCK錯誤;
(7) SO_RCVBUF, SO_SNDBUF:
每個套接字都有一個發送緩沖區和一個接收緩沖區;TCP套接字的緩沖區大小至少應該是MSS的4倍;MSS=MTU-40頭部,一般以太網卡MTU是1500;典型緩沖區默認大小是8192字節或者更大;對於一次發送大量數據,可以增加到48K,64K等;為了達到最佳性能,緩沖區可能至少要與BDP(帶寬延遲乘積)一樣大小;對於接收大量數據的,提高接收緩沖區能夠減少發送端的阻塞;
TCP設置這個兩個選項注意順序:對於客戶端必須在調用connect之前,對於服務器端應該在調用listen之前,因為窗口選項是在建立連接時用syn分節與對端互換得到的;
(8) SO_RCVLOWAT, SO_SNDLOWAT:
每個套接字還有一個接收低水位標記和一個發送低水位標記。他們由select函數使用,接收低水位標記是讓select返回可讀時套接字接收緩沖區中所需的數據量;對於tcp,udp,默認值是1;發送低水位標記是讓select返回可寫時套接字發送緩沖區中所需的可用空間;對於tcp套接字,其默認值通常為2048;
(9) SO_RCVTIMEO, SO_SNDTIMEO:
這兩個選項允許我們給套接字的接收和發送設置一個超時值,注意,訪問getsockopt和setsockopt函數的參數是指向timeval的指針,與select所用的參數相同;
(10) SO_TYPE:
本選項返回套接字的類型,返回的整數值是一個注入SOCK_STREAM或者SOCK_DGRAM之類的值;本選項通常由啟動時繼承了套接字的進程使用;
(11) SO_USELOOPBACK:
本選項僅用於路由域(AF_ROUTE)套接字,默認設置是打開,相應套接字 將接收在其上發送的任何數據報的一個副本;
(12) SO_REUSEADDR:
TCP先調用close()的一方會進入TIME_WAIT狀態,只有設置了SO_REUSEADDR選項的socket,才可以重復綁定使用。server程序總是應該在調用bind之前設置SO_REUSEADDR套接字選項。
這個套接字選項通知內核,如果端口忙,但TCP狀態位於 TIME_WAIT ,可以重用端口。如果端口忙,而TCP狀態位於其他狀態,重用端口時依舊得到一個錯誤信息,指明"地址已經使用中"。如果你的服務程序停止后想立即重啟,而新套接字依舊使用同一端口,此時SO_REUSEADDR 選項非常有用。必須意識到,此時任何非期望數據到達,都可能導致服務程序反應混亂,不過這只是一種可能,事實上很不可能。
3. tcp套接字選項:
(1) TCP_MAXSEG:
本選項允許我們獲取或者設置TCP連接的最大分節大小(MSS)。已建立連接返回的是對端使用syn通知的MSS值,否則是未從對端收到MSS情況下使用的默認值;
(2) TCP_NODELAY:
開啟本選項將禁止TCP的Nagle算法,默認情況下Nagle算法是啟動的;關於Nagle算法,單獨總結一篇;