歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> Unix基礎知識 >> UNIX網絡編程:通用套接字選項

UNIX網絡編程:通用套接字選項

日期:2017/3/3 14:55:28   编辑:Unix基礎知識

1. SO_BROADCAST 套接字選項

本選項開啟或禁止進程發送廣播消息的能力。只有數據報套接字支持廣播,並且還必須是在支持廣播消息的網絡上(例如以太網,令牌環網等)。我們不可能在點對點鏈路上進行廣播,也不可能在基於連接的傳輸協議(例如TCP和SCTP)之上進行廣播。

2. SO_DEBUG 套接字選項

本選項僅由TCP支持。當給一個TCP套接字開啟本選項時,內核將為TCP在該套接字發送和接受的所有分組保留詳細跟蹤信息。這些信息保存在內核的某個環形緩沖區中,並可使用trpt程序進行檢查。

3. SO_KEEPALIVE 套接字選項

給一個TCP套接字設置保持存活選項後,如果2小時內在該套接字的任何一方向上都沒有數據交換,TCP就自動給對端發送一個保持存活探測分節。這是一個對端必須相應的TCP分節,它會導致以下3種情況之一。

(1)對端以期望的ACK響應。應用進程得不到通知(因為一切正常)。在又經過仍無動靜的2小時後,TCP將發出另一個探測分節。

(2)對端以RST響應,它告知本端TCP:對端已崩潰且已重新啟動。該套接字的待處理錯誤被置為ECONNRESET,套接字本身則被關閉。

(3)對端對保持存活探測分節沒有任何響應。

如果根本沒有對TCP的探測分節的響應,該套接字的待處理錯誤就被置為ETIMEOUT,套接字本身則被關閉。然而如果該套接字收到一個ICMP錯誤作為某個探測分節的響應,那就返回響應的錯誤,套接字本身也被關閉。

本選項的功能是檢測對端主機是否崩潰或變的不可達(譬如撥號調制解調器連接掉線,電源發生故障等等)。如果對端進程崩潰,它的TCP將跨連接發送一個FIN,這可以通過調用select很容易的檢測到。

本選項一般由服務器使用,不過客戶也可以使用。服務器使用本選項時因為他們花大部分時間阻塞在等待穿越TCP連接的輸入上,也就是說在等待客戶的請求。然而如果客戶主機連接掉線,電源掉電或者系統崩潰,服務器進程將永遠不會知道,並將繼續等待永遠不會到達的輸入。我們稱這種情況為半開連接。保持存活選項將檢測出這些半開連接並終止他們。

4. SO_LINGER 套接字選項

本選項指定close函數對面向連接的協議(例如TCP和SCTP,但不是UDP)如何操作。默認操作是close立即返回,但是如果有數據殘留在套接字發送緩沖區中,系統將試著把這些數據發送給對端。

5. SO_RCVBUF和SO_SNDBUF套接字選項

每個套接字都有一個發送緩沖區和一個接收緩沖區。

接收緩沖區被TCP,UDP和SCTCP用來保存接收到的數據,直到由應用進程讀取。對於TCP來說,套接字接收緩沖區可用空間的大小限制了TCP通告對端的窗口大小。TCP套接字接收緩沖區不可以溢出,因為不允許對端發出超過本端所通告窗口大小的數據。這就是TCP的流量控制,如果對端無視窗口大小而發出了超過窗口大小的數據,本端TCP將丟棄它們。然而對於UDP來說,當接收到的數據報裝不進套接字接收緩沖區時,該數據報就被丟棄。回顧一下,UDP是沒有流量控制的:較快的發送端可以很容易的淹沒較慢的接收端,導致接收端的UDP丟棄數據報。

這兩個套接字選項允許我們改變著兩個緩沖區的默認大小。對於不同的實現,默認值得大小可以有很大的差別。如果主機支持NFS,那麼UDP發送緩沖區的大小經常默認為9000字節左右的一個值,而UDP接收緩沖區的大小則經常默認為40000字節左右的一個值。

當設置TCP套接字接收緩沖區的大小時,函數調用的順序很重要。這是因為TCP的出口規模選項時在建立連接時用SYN分節與對端互換得到的。對於客戶,這意味著SO_RCVBUF選項必須在調用connect之前設置;對於服務器,這意味著該選項必須在調用listen之前給監聽套接字設置。給已連接套接字設置該選項對於可能存在的出口規模選項沒有任何影響,因為accept直到TCP的三路握手玩抽才會創建並返回已連接套接字。這就是必須給監聽套接字設置本選項的原因。

查看本欄目更多精彩內容:http://www.bianceng.cn/OS/unix/

6. SO_RCVLOWAT 和 SO_SNDLOWAT套接字選項

每個套接字還有一個接收低水位標記和一個發送低水位標記。他們由select函數使用,這兩個套接字選項允許我們修改這兩個低水位標記。

接收低水位標記是讓select返回“可讀”時,套接字接收緩沖區中所需的數據量。對於TCP,UDP和SCTP套接字,其默認值為1。發送低水位標記是讓select返回“可寫”時套接字發送緩沖區中所需的可用空間。對於TCP套接字,其默認值通常為2048。UDP也使用發送低水位標記,然而由於UDP套接字的發送緩沖區中可用空間的字節數從不改變(意味UDP並不為由應用進程傳遞給它的數據報保留副本),只要一個UDP套接字的發送緩沖區大小大於該套接字的低水位標記,該UDP套接字就總是可寫。我們記得UDP並沒有發送緩沖區,而只有發送緩沖區大小這個屬性。

7. SO_RCVTIMEO 和 SO_SNDTIMEO套接字選項

這兩個選項允許我們給套接字的接收和發送設置一個超時值。注意,訪問他們的getsockopt和setsockopt函數的參數是指向timeval結構的指針,與select所用參數相同。這可讓我們用秒數和微妙數來規定超時。我們通過設置其值為0s和0μs來禁止超時。默認情況下著兩個超時都是禁止的。

接收超時影響5個輸入函數:read,readv,recv,recvfrom和recvmsg。發送超時影響5個輸出函數:write,writev,send,sendto和sendmsg。

8. SO_REUSEADDR 和 SO_REUSEPORT 套接字選項

SO_REUSEADDR套接字選項能起到以下4個不同的功用。

(1)SO_REUSEADDR允許啟動一個監聽服務器並捆綁其眾所周知的端口,即使以前建立的將該端口用作他們的本地端口的連接仍存在。這個條件通常是這樣碰到的:

(a)啟動一個監聽服務器;

(b)連接請求到達,派生一個子進程來處理這個客戶;

(c)監聽服務器終止,但子進程繼續為現有連接上的客戶提供服務;

(d)重啟監聽服務器。

默認情況下,當監聽服務器在步驟d通過調用socket,bind和listen重新啟動時,由於他試圖捆綁一個現有連接(即正由早先派生的那個子進程處理著的連接)上的端口,從而bind調用會失敗。但是如果該服務器在socket和bind兩個調用之間設置了SO_REUSEADDR套接字選項,那麼將成功。所有TCP服務器都應該指定本套接字選項,以允許服務器在這種情況下被重新啟動。

(2)SO_REUSEADDR允許在同一端口上啟動同一服務器的多個實例,只要每個實例捆綁一個不同的本地IP地址即可。對於TCP,我們絕對不可能啟動捆綁相同IP地址和相同端口號的多個服務器:這是完全重復的捆綁,即使我們給第二個服務器設置了SO_REUSEADDR套接字也不管用。

(3)SO_REUSEADDR 允許單個進程捆綁同一端口到多個套接字上,只要每次捆綁指定不同的本地IP地址即可。

(4)SO_REUSEADDR允許完全重復的捆綁:當一個IP地址和端口號已綁定到某個套接字上時,如果傳輸協議支持,同樣的IP地址和端口還可以捆綁到另一個套接字上。一般來說本特性僅支持UDP套接字。

查看本欄目更多精彩內容:http://www.bianceng.cn/OS/unix/

Copyright © Linux教程網 All Rights Reserved