目錄
前言:
局域網+協議
MAC/IP地址
Socket編程
TCP/UDP
網絡字節序
前言:
本文同樣作為博主的二刷網絡課程的文章,主要涵蓋的主題還是網絡基本概念的認識,從上一篇文章遺漏的點加上引入的一些知識點共同組成當前的知識點。
在這篇文章收尾之后,我們就會開始愉快的TCP UDP IP ARP Cookie Session......之旅,所以在面臨風暴之前,我們還是盡可能的將網絡基礎部分理解吧。
那么本文的重點在于:局域網的分類,第二次認識協議,認識MAC地址IP地址,理解網絡通信中的socket編程等。
當然了,重點在于...其實都是重點哈哈哈。
那么廢話不多說,我們直接進入主題吧!!
局域網+協議
對于局域網和協議來說,咱們要理解的實際上沒有那么多,所以博主這里將兩個知識點放在了一起。
對于局域網來說,是有很多很多種的,而網絡的誕生就像武功問世一樣,不同的人整出了不同的幫派,只有那些最牛逼的幫派才能活到最后。
所以局域網也是這樣的,目前比較流行的局域網有令牌環,以太網,WLAN等等,其中我們就重點解釋一下令牌環和以太網。
首先是以太網:
看到中間的那個圈了吧,我們如果把這個圈看成是以太網的話,那么不同的端系統,也就是主機接入以太網之后,就需要開始收發數據了吧?
那么在以太網中收發數據需要遵守幾個原則:發數據的時候只能有一個發數據,收數據的時候可以有多個主機同時收。
如果多臺主機同時發送數據,就會發送稱為數據碰撞的情況,而對于所有發送數據的主機都需要進行碰撞檢測和碰撞避免,那么在這種情況下,一個以太網就是一個碰撞域。
當數據發送到以太網之后,就需要通過MAC地址和IP地址來傳遞了,這個咱們后面談,我們對于以太網有一個非常淺薄的認識就可以了。
接著是令牌環,對于令牌環我們是非常好理解的,因為我們是有鎖的基礎的,所以我們不妨把令牌看作是一個鎖,誰有令牌誰就可以發數據,這就非常非常簡單的理解了什么是令牌環。
然后是再認識協議了。
怎么說呢,對于協議來說,是整個網絡世界的硬貨,它是兩臺或多臺主機之間的約定,是對于收發數據操作的一個統一吧。
不過我們之前已經有了對協議的第一層理解,現在我們將理解協議的第二層:
咱們就拿這個圖舉例吧,左邊是Windows系統,右邊是Linux系統,首先就會有人提問疑問:
兩個不同的系統也能夠通信嗎?
首先,對于不同系統的網絡協議棧來說,都是一樣的,比如操作系統中的傳輸層和網絡層的底層代碼也差不到哪里去,也就意味著它們的API都是一樣的,調用的接口都是一樣的,都是C語言寫的,數據格式也都是一樣的,用的協議都是一樣的,屏蔽操作系統其他的差異,就拿網絡協議棧來說,如此多的共同點,難道不足以支撐它們通信嗎?
那么問題來了,這和我們今天介紹的協議有什么關系嗎?請注意我在上文提及到了數據格式都是一樣的,那么你說,如果我從A主機定義了一個結構體,里面有int類型的三個變量,a,b,c,實例化了之后給B,你說B能讀取到嗎?
當然是可以的!
為什么可以?A給B一個數據,B不管是用拷貝的方式來接收還是用指針指向的方式來接收都可以,問題是為什么它可以,因為B中的數據格式是和A中的數據格式一樣的,你想,如果B沒有這個結構體,它能解析這個數據嗎?它不能解析。
所以實際上,我們不用把協議想的太復雜了,它實際上就是雙方都認識的一個結構化數據,就像咱們日常交流一樣,我們都認識一個結構化數據叫做中文,所以我們可以無障礙交流。
到此,我們對于協議的第二層認識就出來了:協議是通信雙方都認識的一個數據!
MAC/IP地址
介紹MAC和IP地址我們拿這張圖作為例子,數據從應用層開始傳輸,傳輸的時候會填報文吧?報文里面有源IP和目的IP地址,這里的IP地址就是不同主機的在網絡中的地址,你可以理解為現實中咱們的家庭地址。
那么IP地址的具體組成:
一、IPv4地址
IPv4地址由?32位二進制數?組成,通常以?點分十進制?格式表示(如?
192.168.1.1
)。1. 基本結構
4個十進制字段:每個字段占8位(1字節),范圍為?
0~255
,用點分隔。
示例:192.168.1.1
?→ 二進制為?11000000.10101000.00000001.00000001
。2. 網絡部分與主機部分
網絡號(Network ID):標識設備所屬的網絡。
主機號(Host ID):標識網絡中的具體設備。
子網掩碼:用于劃分網絡號和主機號。
示例:255.255.255.0
(二進制為?11111111.11111111.11111111.00000000
)表示前24位是網絡號,后8位是主機號。3. 分類(傳統方式)
A類地址:首位為?
0
,網絡號占8位(范圍:1.0.0.0~126.255.255.255
)。B類地址:前兩位為?
10
,網絡號占16位(范圍:128.0.0.0~191.255.255.255
)。4. CIDR(無類域間路由)
使用?斜線表示法(如?
192.168.1.0/24
),/24
?表示前24位是網絡前綴。C類地址:前三位為?
110
,網絡號占24位(范圍:192.0.0.0~223.255.255.255
)。D類(組播)和?E類(保留)地址。
這上面的是DS生成的,我們暫時先了解一下,畢竟后面我們會詳細介紹IP的。?
那么數據在傳輸的過程,會有一個動作,叫做路由,經過了路由就可以轉接到正確的IP地址去,那么比如這里的SRC是192開頭,DST是172開頭,也就代表了這兩個IP地址不在一個局域網,所以自然需要經過路由這個操作來讓數據包走向正確的IP地址。
那么MAC地址又是怎么回事呢?對于MAC地址來說,它就是一個臨時的,會隨時變化的地址,比如路由這個操作有的時候要經過多次的轉接,那么在轉接的時候,你像A到B,B到C這里總會有一個中間地址C吧?
所以MAC地址就是臨時的地址,它可以是路由器的地址,也可以是其他端設備的地址。
你要是覺得不好理解,你這樣想,西天取經知道吧?唐僧的源IP是長安,目的IP是西天,MAC地址就是途中的車遲國啊,女兒國一類的。
而在封包的這個過程中,源IP和目的IP是一直不變的,其中的MAC地址就會隨著封包的過程不斷變化。
就像這樣,以上是對于IP地址和MAC地址的解釋。
Socket編程
到現在我們對于網絡基礎的純概念部分已經了解了一些了,接下的理論基礎就是為了編程方面操作了。
首先,我們要清楚,網絡通信的本質是什么?
對于兩個主機AB來說,它們真正要通信的不是兩個主機之間進行通信,而是這臺主機中的哪個進程要通信,比如我打開抖音,我是要通過抖音這個軟件和字節跳動的服務器進行交互,而不是我這部手機要和字節跳動的機器交互。
所以網絡通信的本質是什么呢?實際上是進程間通信!!
到這里同學是否會覺得和之前的系統編程有了聯系?
好了,既然我們知道是進程間通信,下一個問題是,我們如何讓信息精準無誤的傳輸到我們想要的進程那里去?
在系統編程的時候我們了解到了進程有PID的概念,也就是在系統中唯一標識了系統的序列號,那么在網絡中我們是否沿用PID還是再來一個網絡方面的序列號呢?
首先,我們需要對方主機的IP這是肯定的,這是第一大點,需要對方的主機IP。
其次,在網絡中我們單獨引了一個概念叫做端口號,這個端口號的作用呢就相當于系統中的PID,所以端口號的作用就是標識主機中某個進程的。
那么在網絡世界中,我們有了IP地址和端口號,我們就可以找到網絡中的唯一一個進程。此時我們通信的可靠性就增加了。
那么端口號一般是:
0-1023:知名端口號,HTTP,FTP,SSH等這些廣為使用的應用層協議,他們的端口號都是固定的.
1024-65535:操作系統動態分配的端口號.客戶端程序的端口號,就是由操作 系統從這個范圍分配的.
比如HTTP的端口號都是80 HTTPS又是另一個。
所以Socket編程的Socket其實是等于IP + port。
那么有人問了,為什么要用所謂的端口號而不是PID,PID多方便,還不用單獨生成。
實則不然,如果我們繼續沿用PID的話,那么系統和網絡就會發生強耦合,這當然是不好的,強耦合帶來的壞處不言而喻,一個錯了導致另一個接著錯,并且,對于端口號來說,不是所有的進程都需要端口號,一臺機器上能進行通信的進程實際上沒有那么多,所以即便不考慮解耦合的話,有些進程根本都不需要通信,我們還要它PID干嘛呢,不如我們單獨拿一個概念出來專門為了通信。
其實主要就是為了解耦合。
TCP/UDP
我們現在也可以簡單理解一下傳輸層的兩個大頭,一個是TCP協議一個是UDP協議,對于TCP協議來說具有的特點是:有連接,面向字節流,可靠傳輸。對于UDP協議來說具有的特點是無連接,面向數據報,不可靠傳輸。
咱們一定要記住,上面的三個短句是它們的特點而不是所謂的優缺點。
這點我們在后面實現代碼和學習它們本質的時候會了解到。
網絡字節序
相信大家都知道大小端機器的差別,一個是低權重值低地址位,這是小端機器,高權重低地址位這是大端機器,那么如果大小端機器進行通信,假設發送的是同一份數據,但是因為大小端的差別導致它們得到的信息是相反的,這肯定是不行的,所以網絡中引入了一個新的概念叫做網絡字節序,實際上這個網絡字節序就是大端的意思,代表上傳到網絡的數據必須是大端,接收數據也是。
至于怎么轉換大小端,這咱們就不要關心了,函數已經幫我們實現好了。
那么這里至少涉及到的函數有:
uint32_t htonl(uint32_t hostlong);
uint32_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t hostlong);
uint32_t htohs(uint16_t hostshort);
其中對于函數h的意思代表host主機,l代表long,長整數,s代表short短整數,n代表network。
也就是這幾個函數代表是從主機轉網絡還是從網絡轉主機。
好了,接下來我們了解了數據的傳輸方面,在了解一下IP地址常用的結構體,其中對于IPv4和IPv6都是用的sockaddr_in結構體,不過是參數方面不同而已,而對于sockaddr_un只能說我們一般都用不到,這是Unix域套接,怎么說呢,咱們不妨大手一揮,不用管它。
在網絡世界中,因為Socket編程的API都是通用的,所以參數也是通用的,那么問題來了,這上面明明結構體不同啊,怎么會通過API呢?
實際上引入了sockaddr參數,當我們傳入sockaddr_in和sockaddr_un的時候,需要強轉一下就可以了。
并且你看這幾個結構體的參數也是一摸一樣的,你猜猜這是C語言的什么?
這不就是C語言的繼承和多態嗎!!!
好了,以上是理論基礎的所有鋪墊。
感謝閱讀!