1. 程式人生 > >IP地址、埠號、網路位元組序

IP地址、埠號、網路位元組序

一.IP地址1. 簡單認識    IP協議有兩個版本:IPv4和IPv6。        (1)IP地址在IP協議中,用來標識網路中不同主機的地址。        (2)對於IPv4來講,IP地址是一個4位元組,32位的整數;對於IPv6來講,IP地址是一個16位元組,128位的整數。(3)我們常用“點分十進位制“的字串表示IP地址,例如:192.168.2.13,其中用點分割的每一個數字表示一個位元組,範圍是0-255。2. 源IP地址與目的IP地址        在IP資料的包頭資訊中,有兩個IP地址,分別叫做源IP地址、目的IP地址。        因為,我們不僅要知道資料是誰發的,也要知道資料是要發給誰的。二. 埠號  
        我們僅僅知道IP地址,知道該把資料傳送給哪臺機器是遠不夠的。我們還需要知道這些資料是要發給機器哪個程式進行解析,所以我們需要一個其他的標識,所以就有了“埠號”。1. 簡單認識    埠號是傳輸層協議的內容。        (1)埠號是一個2位元組16位的整數;        (2)埠號用來標識一個程序,告訴作業系統,當前的資料要交給哪一個程序來處理;        (3)所以“IP地址+埠號”即套接字socket可以唯一地標識某一臺主機上的某一個程序;        (4)一個埠號只能被一個程序佔用。2. 區分“埠號”和“程序ID”        之前,我們學程序章節的時候,也說過程序ID可以表示唯一的一個程序。拿這兩者的不同在什麼地方呢?       舉個例子吧,比如學號和身份證號。程序的PID相當於一個人的身份證號,在任何地方都唯一標識某個人,而埠號相當於一個學號,它只在學校裡來唯一標識一個學生。因此,PID無論在哪裡都可以唯一標識一個程序,而埠號只在網路通訊中來唯一標識一個程序。
另外,一個程序可以繫結多個埠號,因為很多源主機可以通過不同的埠號來找到目的主機中的同一程序來處理不同的資料。但是一個埠號不能被多個程序繫結,如果一個埠號綁定了多個程序,那多個程序都對同一資料進行處理,那要採取那個程序返回的結果呢,我們無法確定。3. 源埠號和目的埠號        傳輸層協議(TCP和UDP)的資料段中有兩個埠號,分別叫做源埠號和目的埠號。分別用於描述:資料是誰發的,資料要發給誰。三. 網路位元組序當我們將源主機中的資料傳送給目的主機時,是如何傳送的呢?根據馮諾依曼體系結構,我們知道源主機要通過記憶體將資料先發給源主機的外設(網絡卡),然後傳送到網路中,目的主機將網路中的資料項接收到目的主機的網絡卡上,再傳入到目的主機的記憶體中,然後通過CPU對資料進行處理。
而資料在記憶體中的儲存有大小端之分。如果在源主機的記憶體為小端,而目的主機以大端的形式來接受資料時,此時,就會導致資料錯誤。而不僅不同主機的大小端不同,在網路序列中也有大小端之分。這樣一來,就更加混亂了。所以,TCP/IP協議規定,網路資料流均採用大端,即低地址處放資料的高位       如果源主機為小端則在傳送資料時應先轉為大端,如果是大端,則不用轉化。然後將大端資料存放在傳送緩衝區中,直接傳送到網路中即可。

        當目的主機在接受訊息時,先將網路中的大端資料儲存到接受緩衝區中。如果目的主機是小端,則將大端資料轉換為小端儲存到記憶體中,如果目的主機是大端則不用轉換直接儲存到記憶體中。

同時,有以下規定:        傳送主機通常把傳送緩衝區中的資料按記憶體地址從低到高的順序發出;        接收主機把從網路上接到的位元組依次儲存在接收緩衝區中,也是按記憶體地址從低到高的順序儲存;        因此,網路資料流的地址應該這樣規定先發出的資料是低地址,後發出的資料是高地址。所以,我們有以下庫函式做網路位元組序和主機位元組序的轉換:
  1. #include <arpa/inet.h>
  2. uint32_t htonl(uint32_t hostlong);  
  3. uint16_t htons(uint16_t hostshort);  
  4. uint32_t ntohl(uint32_t netlong);  
  5. uint16_t ntohs(uint16_t netshort);  
        其中,h代表host即主機,n表示network即網路,l表示32長整數,s表示16位短整數。所以比如htonl函式是將32位的長整型從主機位元組序轉換為網路位元組序,其他函式類似。        若主機是小端位元組序,這些函式將引數做相應的大小端轉換然後返回; 若主機是小端位元組序,這些函式將不做轉換,將引數原封不動地返回。