天天看點

《UNIX網絡程式設計 卷1:套接字聯網API(第3版)》——2.9 端口号

本節書摘來自異步社群《unix網絡程式設計 卷1:套接字聯網api(第3版)》一書中的第2章,第2.9節,作者:【美】w. richard stevens , bill fenner , andrew m. rudoff著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

任何時候,多個程序可能同時使用tcp、udp和sctp這3種傳輸層協定中的任何一種。這3種協定都使用16位整數的端口号(port number)來區分這些程序。

當一個客戶想要跟一個伺服器聯系時,它必須辨別想要與之通信的這個伺服器。tcp、udp和sctp定義了一組衆所周知的端口(well-known port),用于辨別衆所周知的服務。舉例來說,支援ftp的任何tcp/ip實作都把21這個衆所周知的端口配置設定給ftp伺服器。配置設定給簡化檔案傳送協定(trivial file trqnsfer protocol,tftp)的是udp端口号69。

另一方面,客戶通常使用短期存活的臨時端口(ephemeral port)。這些端口号通常由傳輸層協定自動賦予客戶。客戶通常不關心其臨時端口的具體值,而隻需确信該端口在所在主機中是唯一的就行。傳輸協定的代碼確定這種唯一性。

iana(the internet assigned numbers authority,網際網路已配置設定數值權威機構)維護着一個端口号配置設定狀況的清單。該清單一度作為rfc多次釋出;rfc 1700[reynolds and postel 1994]是這個系列的最後一個。端口号被劃分成以下3段。

(1)衆所周知的端口為 0~1023。這些端口由iana配置設定和控制。可能的話,相同端口号就配置設定給tcp、udp和sctp的同一給定服務。例如,不論tcp還是udp端口号80都被賦予web伺服器,盡管它目前的所有實作都單純使用tcp。

端口号80配置設定時sctp尚不存在。新的端口配置設定将針對這3種協定執行,rfc 2960則聲明所有現有的tcp端口号對于使用sctp的同一服務同樣有效。

(2)已登記的端口(registered port)為1024~49151。這些端口不受iana控制,不過由iana登記并提供它們的使用情況清單,以友善整個群體。可能的話,相同端口号也配置設定給tcp和udp的同一給定服務。例如,6000~6063配置設定給這兩種協定的x window伺服器,盡管它的所有實作目前單純使用tcp。49151這個上限的引入是為了給臨時端口留出範圍,而rfc 1700[reynolds and postel 1994]所列的上限為65535。

(3)49152~65535是動态的(dynamic)或私用的(private)端口。iana不管這些端口。它們就是我們所稱的臨時端口。(49152這個魔數是65536的四分之三。)

圖2-10展示了端口号的劃分情況和常見的配置設定情況。

《UNIX網絡程式設計 卷1:套接字聯網API(第3版)》——2.9 端口号

我們要注意圖2-10中以下幾點。

unix系統有保留端口(reserved port)的概念,指的是小于1024的任何端口。這些端口隻能賦予特權使用者程序的套接字。所有iana衆所周知的端口都是保留端口,配置設定使用這些端口的伺服器(例如ftp伺服器)必須以超級使用者特權啟動。

由于曆史原因,源自berkeley的實作(從4.3bsd開始)曾在1024~5000範圍内配置設定臨時端口。這在20世紀80年代初期是可行的,但是如今很容易就找到一個在任何給定時間内同時支援多于3977個連接配接的主機。于是許多較新的系統從另外的範圍配置設定臨時端口以提供更多的臨時端口,它們或者使用由iana定義的臨時端口範圍,或者使用一個更大的其他範圍(如圖2-10所示的solaris)。

由于這個原因,許多較早的系統實作的臨時端口範圍的上限為5 000。5 000這個上限後來發現是一個排版錯誤[borman ],本應該是50 000。

有少數客戶(而不是伺服器)需要一個保留端口用于客戶/伺服器的認證:rlogin和rsh客戶就是常見的例子。這些客戶調用庫函數rresvport建立一個tcp套接字,并賦予它一個在513~1023範圍内未使用的端口。該函數通常先嘗試綁定端口1023,若失敗則嘗試1022,依次類推,直到在端口513上亦或成功,亦或失敗。

注意:bsd的保留端口和rresvport函數都跟iana衆所周知端口的後半部分重疊。這是因為iana衆所周知端口早先的上限為255。1992年的rfc 1340(早先的一個"assigned numbers"rfc)開始在256~1023之間配置設定衆所周知的端口。1990年的rfc 1060(更早先的一個"assigned numbers"rfc)稱256~1023之間的端口為unix标準服務(unix standard services)。20世紀80年代有不少源自berkeley的伺服器在512以後挑選它們的衆所周知的端口(留下256~511這個空檔)。rresvport函數選擇從1023開始往下尋找,直至513。

套接字對

一個tcp連接配接的套接字對(socket pair)是一個定義該連接配接的兩個端點的四元組:本地ip位址、本地tcp端口号、外地ip位址、外地tcp端口号。套接字對唯一辨別一個網絡上的每個tcp連接配接。就sctp而言,一個關聯由一組本地ip位址、一個本地端口、一組外地ip位址、一個外地端口辨別。在兩個端點均非多宿這一最簡單的情形下,sctp與tcp所用的四元組套接字對一緻。然而在某個關聯的任何一個端點為多宿的情形下,同一個關聯可能需要多個四元組辨別(這些四元組的ip位址各不相同,但端口号是一樣的)。

辨別每個端點的兩個值(ip位址和端口号)通常稱為一個套接字。

我們可以把套接字對的概念擴充到udp,即使udp是無連接配接的。當講解套接字函數(bind、

connect、getpeername等)時,我們将指明它們在指定套接字對中的哪些值。舉例來說,bind函數要求應用程式給tcp、udp或sctp套接字指定本地ip位址和本地端口号。

繼續閱讀