Socket的基本背景
在討論這兩個選項的區(qū)別時,我們需要知道的是BSD實現(xiàn)是所有socket實現(xiàn)的起源。基本上其他所有的系統(tǒng)某種程度上都參考了BSD socket實現(xiàn)(或者至少是其接口),然后開始了它們自己的獨立發(fā)展進化。顯然,BSD本身也是隨著時間在不斷發(fā)展變化的。所以較晚參考BSD的系統(tǒng)比較早參考BSD的系統(tǒng)多一些特性。所以理解BSD socket實現(xiàn)是理解其他socket實現(xiàn)的基石。下面我們就分析一下BSD socket實現(xiàn)。
在這之前,我們首先要明白如何唯一識別TCP/UDP連接。TCP/UDP是由以下五元組唯一地識別的:
{<protocol>, <src addr>, <src port>, <dest addr>, <dest port>}這些數(shù)值組成的任何獨特的組合可以唯一地確一個連接。那么,對于任意連接,這五個值都不能完全相同。否則的話操作系統(tǒng)就無法區(qū)別這些連接了。
一個socket的協(xié)議是在用socket()初始化的時候就設(shè)置好的。源地址(source address)和源端口(source port)在調(diào)用bind()的時候設(shè)置。目的地址(destination address)和目的端口(destination port)在調(diào)用connect()的時候設(shè)置。其中UDP是無連接的,UDP socket可以在未與目的端口連接的情況下使用。但UDP也可以在某些情況下先與目的地址和端口建立連接后使用。在使用無連接UDP發(fā)送數(shù)據(jù)的情況下,如果沒有顯式地調(diào)用bind(),草錯系統(tǒng)會在第一次發(fā)送數(shù)據(jù)時自動將UDP socket與本機的地址和某個端口綁定(否則的話程序無法接受任何遠程主機回復(fù)的數(shù)據(jù))。同樣的,一個沒有綁定地址的TCP socket也會在建立連接時被自動綁定一個本機地址和端口。
如果我們手動綁定一個端口,我們可以將socket綁定至端口0,綁定至端口0的意思是讓系統(tǒng)自己決定使用哪個端口(一般是從一組操作系統(tǒng)特定的提前決定的端口數(shù)范圍中),所以也就是任何端口的意思。同樣的,我們也可以使用一個通配符來讓系統(tǒng)決定綁定哪個源地址(ipv4通配符為0.0.0.0,ipv6通配符為::)。而與端口不同的是,一個socket可以被綁定到主機上所有接口所對應(yīng)的地址中的任意一個。基于連接在本socket的目的地址和路由表中對應(yīng)的信息,操作系統(tǒng)將會選擇合適的地址來綁定這個socket,并用這個地址來取代之前的通配符IP地址。
在默認情況下,任意兩個socket不能被綁定在同一個源地址和源端口組合上。比如說我們將socketA綁定在A:X地址,將socketB綁定在B:Y地址,其中A和B是IP地址,X和Y是端口。那么在A==B的情況下X!=Y必須滿足,在X==Y的情況下A!=B必須滿足。需要注意的是,如果某一個socket被綁定在通配符IP地址下,那么事實上本機所有IP都會被系統(tǒng)認為與其綁定了。例如一個socket綁定了0.0.0.0:21,在這種情況下,任何其他socket不論選擇哪一個具體的IP地址,其都不能再綁定在21端口下。因為通配符IP0.0.0.0與所有本地IP都沖突。
新聞熱點
疑難解答
圖片精選