2016-08-12 64 views
0

要創建packet socket,以下socket()函數調用被使用(插座類型和協議可以是不同的):爲什麼在創建包套接字時使用htons()指定協議?

socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

而創建stream socket,下面的調用用於:

socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)

我的問題是爲什麼在創建packet socket時使用htons()指定協議,而不是在創建AF_INET or AF_INET6家族的套接字時指定協議?爲什麼不使用

socket(AF_INET, SOCK_XXX, htons(IPPROTO_XXX))

創建一個流或數據報套接字作爲創建packet socket或反之亦然時使用。在socket()函數的兩個調用中使用協議有什麼不同,因爲這兩個調用都用於創建套接字,一個用於數據包套接字,另一個用於TCP層的套接字?

回答

0

首先,與傳遞給內核的大多數其他網絡參數(IP地址,端口等)一樣,參數以「在線」格式傳遞,因此底層軟件無需操作他們在比較/複製/傳輸/等之前。 (爲了比較,考慮到AF_PACKETSOCK_RAW是內核本身的參數 - 因此「原始格式」是合適的 - 而ETH_P_xxx值通常用於「與輸入數據包比較」;恰巧ETH_P_ALL是一個特殊信號值說'捕獲一切'。)

其次,協議的解釋可能是不同的地址家庭。不同的地址系列可以選擇以任何形式對該協議進行解釋。恰恰是以太網和IP一直使用big-endian(並且很重要/無處不在,以至於big-endian被稱爲網絡訂單)。第三,AF_INET世界(即互聯網協議)中的協議號碼只佔用一個字節,因此指定字節排序是沒有意義的。

+0

Ethernet *和* IP *標頭的在線格式*稱爲網絡字節順序(正如我在第二段中所解釋的)。你可以把你想要的任何順序「在電線上」。 –

+0

對於第1段,考慮到ETH_P_XXX值是「與傳入數據包的比較」,那麼爲什麼IPPROTO_XXX值沒有轉換爲網絡字節順序。我明白第二段給出了上述問題的原因,即不同的協議族可以選擇以對其有意義的形式來解釋協議。那麼這是否意味着它是功能開發人員的決定,因爲他可以選擇將函數內部的協議轉換?對於第三段,協議號是作爲int傳遞的,所以字節順序確實有意義。如果我錯了,請糾正。 – rht

+0

這樣想:如果你在小端機器上比較兩個16位值。有兩種比較方法:(a)逐字節比較它們在存儲器中出現的順序,(b)將16位單元加載到寄存器中,然後進行比較。另一方面,對於單字節值,這兩種方式都是相同的。 –