關於網絡編程套接字的基礎知識

爲了方便後邊更好地理解網絡套接字編程,先介紹一些重要的概念。

IP地址

IP地址是在IP協議中用來標識網絡中不同主機的地址。它有兩個版本:IPv4 和 IPv6

IPv4:IP地址由4個字節(0~255)構成,共32位。

IPv6:IP地址由16個字節(0~255)構成,共128位。

接下來主要學習IP地址爲IPv4,在機器內部存的是一個4個字節,16位的數據,對於我們來說,是不好記憶的。就想我們在寄一個人的電話號碼的時候會把它分爲類似於前三位,中間四位和後邊四位這樣的方式來記憶。同樣的爲了方便我們對IP地址的記憶,通常使用“點分十進制”的字符串來表示IP地址,例如192.168.3.128;用點來分割的每一個數字表示一個字節,數字的範圍是0~255。這樣相對來說就有好記很多。

源IP地址和目的IP地址和MAC地址。

我們可以將從一個主機向另一個主機發送一段數據的過程比作是在網上購物的過程,那麼賣家給我們發貨的地址就叫做源IP地址,而我們填的收穫地址就叫做目的IP地址。當賣家發貨之後,我們可以查看物流,經常會看到類似於這樣的話,您的快遞已經到達[廣州分撥中心]下一站[西安分撥中心],這裏的廣州分撥中心和西安分撥中心就是MAC地址。通常,我們的快遞都是幾經周折纔到我們手中的,中間的地址一直變,但是發貨地址和收穫地址是一直沒有變化的,也就是說,在一次數據傳輸過程中,MAC地址是會變化的,但是源IP地址和目的IP地址是不會變的。

 

端口號

端口號是一個2字節(16位)的整數,用來標識一個進程。兩個主機依靠網絡進行通信,肯定是通過分屬於兩個主機的進程在進行通信,那麼兩個進程是怎麼找到彼此的呢?先通過IP地址(IP地址就標識了一臺主機)找到對方進程所屬的那臺主機。但是一臺主機裏邊可能同時執行了對個進程,這個時候就需要依靠端口號來告訴操作系統,是哪個進程在與之通信,當前的這些數據要交給這個進程來處理。

我們都知道,每一個進程都有一個進程ID來標識。那麼爲什麼還要用一個端口號來標識一個進程呢?端口號和進程ID有什麼區別呢?

其實,進程ID就相當於是我們的身份證號。我們每個人都有,且是唯一的。但是,身份證有一個缺點,就是比較長(當然現實中身份證還是屬於比較隱私的東西,不能隨便告知別人),也不好記憶。當我們進到一家公司工作,會給我們一個工號。這個工號相當於就是端口號。雖然在公司裏邊也可以用一個身份證來標識每一個員工,但是一家公司根本不可能說擁有相當於全中國人口那麼多的員工。可能就幾萬人甚至幾千人,只需要用5位數就可以將所有人都標記出來,而身份證有18位。而且,可能某個人很是優秀,身兼多職,那麼對於他所處的每個職位,可能就對應一個不同的工號。同樣的,一個進程也可以有多個端口號。雖然說端口號是用於標識一個進程的,但並不是所有的進程都有端口號。端口號是用於在網絡中標識一個進程的,只有訪問網絡的進程纔會有端口號。其實這也很好理解,你都沒有進入別人的公司,沒有成爲公司的員工,公司肯定不會說硬塞給你一個工號吧。

 

網絡字節序

一個主機通過網絡將數據發送到另一個主機的過程中,數據的發送和接收時的字節的處理順序

發送主機通常將發送緩衝區中的數據按內存地址由低到高的順序發出;

接收主機把從網絡上接到的字節一次保存到接收緩衝區中,也是按照由低到高的順序保存。

機器都是有大小端之分的,有的機器是大端的,有的機器是小端的。如果一個大端的機器想和一個小端的機器進行通信,如果對數據進行一些處理,就會發生這樣的情況:源主機A以大端的方式將數據傳送出去,而目的主機B並不知道對方是大端的方式發送的,然後B主機一小端的方式將數據進行接收,很顯然,這就出現問題了。發送和收到的數據根本就不一致。

所以,爲了避免上述情況發生,也就是主機的大小端模式的不一樣導致發送和接收的收據不一致的問題。網絡數據流的地址應該這樣規定:先發出的數據是低地址,後發出的數據是高地址。

TCP/IP協議規定,網絡數據流應該採用大端字節序,即低地址存高字節。

不管這臺主機是大端模式的還是小端模式的,都會按照這個TCP/IP規定的網絡字節序列來發送/j接收數據。

如果當前發送主機是小端,就需要先將數據轉成大端再發送。

具體轉的方法系統已經幫我們實現了,只需要調用一下系統給出的接口就可以了系統爲我們提供哪些接口呢?

 

#include <arpa/inet.h>

uint32_t    htonl(uint32_t hostlong);

uint16_t    htons(uint16_t hostshort);

uint32_t    ntohl(uint32_t hostlong);

uint16_t    ntohs(uint16_t hostshort);

 

這些函數看着很相似,可能會覺的不太好記憶。所以,理解各個函數的含義有助於我們的記憶。函數名中的 h 代表 host(本地) , n 表示 network(網絡) 。l 表示 long(32位長整型),s 表示 short(16位短整數)。htonl 就表示將32位的長整型從主機字節序列轉換爲網絡字節序列,比如說將IP地址轉換後準備發送。

如果主機是小字節序,這些函數將參數做相應的大小端轉換後返回;如果主機是大端字節序,則什麼都不處理,直接將參數返回。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章