TCP/IP協議概念通俗講解, 端口號與套接字的區別

網上對TCPIP協議、以及端口號、套接字以及綁定的概念已經寫的很多了。但不是所有的都適合新手,最近下進行FreeRTOS+TCP開發時,發現官方的解釋特別通俗易懂,因此對我對簡介部分進行了翻譯,方便懶得看英文的人也能瞧瞧,內容來源於:https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html。翻譯裏設計的部分程序中的宏定義的說明,不關心的人自行忽略就是。

 

以太網:數據以以太網幀的方式再本地以太網中傳輸。

以太網地址:以太網通過網絡用於將數據從一個節點搬運到另一個節點。以太網幀中的數據可能只是原始數據,但通常與另一個協議(如Internet協議(IP))相關聯,而IP協議又可能攜帶更多的協議,如UDP或TCP。

同一以太網中的不同節點用它們的MAC地址(硬件地址)來加以區分。MAC地址通常寫爲6字節(8位值),用冒號分隔,例如00:12:34:56:78:90。本地以太網中的每個節點必須有一個唯一(unique)的MAC地址。

MTU:MTU代表最大傳輸單元,是硬件(物理層)的一個特性。MTU的大小以字節(octets )爲基本單位。

MTU Size:

MTU大小定義了發送到網絡或從網絡接收到的數據包或幀的最大大小。如果應用程序發送一小塊的適合一個幀發送的數據,那麼僅僅一個幀將被髮送到網絡上。如果應用程序發送的數據塊大於MTU的大小,那麼數據將被分成多個包,每個包將創建一個小於或等於MTU大小的幀。(注:區分包和幀的概念)

在FreeRTOS+TCP程序中,MTU以字節爲單位指定,並由FreeRTOSIPConfig.h中的 ipconfigNETWORK_MTU 設置。一些MAC設備被限制在1400。

IP:

Internet協議是TCP/IP和UDP/IP中的“IP”。IP協議簇(suit)是被用於如因特網這樣的跨網絡(內部網絡)通信的協議。每個IP網絡中的節點由它們的IP地址標識。IP數據包可以用以太網幀來傳輸(be carried in),也可以用於傳輸(carry)TCP和UDP數據。

IP地址

同一IP網絡上的不同節點由它們的IP地址標識。例如,您正在用來閱讀本文的計算機上的每個網絡接口將具有不同的IP地址。又如,您的計算機所連接的網絡上的每個遠程接口(remote interface )也將具有不同的IP地址。

有兩種常用的IP地址格式。目前,絕大多數遠程地址使用IPv4格式,這是一個32位的數字,但最常見的寫法是四個由點分隔的8位字節(8位數字)。例如“192.168.0.32”。

ARP:

ARP代表地址解析協議。

IP數據包是在IP地址之間發送的,但是封裝它們的以太網幀是在MAC(硬件)地址之間發送的。因此,在將IP包發送到以太網之前,必須知道目標IP地址的MAC地址。

地址解析協議(ARP)用於獲取MAC地址信息。FreeRTOS+TCP(與大多數(如果不是所有的話)IP棧一樣)將IP地址存儲到一個ARP表(有時稱爲ARP緩存)中的MAC地址映射。ARP由TCP/IP協議棧(stack)自動處理。

子網 Subnet:

網允許將IP地址的最重要位解釋爲路由信息,而將IP地址的最不重要位解釋爲本地IP網絡上的唯一節點地址。本地IP網絡(子網)是不使用網關或路由器就可以尋址的網絡。子網之間的通信必須通過路由器。

子網掩碼 Netmask:

被解釋爲包含路由信息的位數由子網掩碼決定。在子網掩碼中設置一個位意味着該位被解釋爲路由信息。例如,如果IP地址是10.134.134.10,網掩碼是255.255.0.0,則10.134提供路由信息,134.10提供本地地址信息。從10.134開始的IP地址可以直接發送到它們在本地網絡上的目的地。以任何其他數字開頭的IP地址不在本地網絡上,因此必須發送到路由器。

路由器 Router:

網絡掩碼用於將IP地址細分爲提供路由信息的字節和提供本地地址信息的字節。如果用子網掩碼按位處理的目標IP地址與用子網掩碼按位處理的本地IP地址不匹配,則兩個IP地址在同一網絡上不存在。在這種情況下,發送到目標地址的包不能直接發送,必須發送到路由器進行智能的網絡間路由。

網關 Gateway

網關地址是路由器的IP地址——路由器是通往其他(遠程)網絡的網關。

FreeRTOS+TCP確定一個IP包是否可以直接發送,或者是否需要發送到路由器。FreeRTOS+TCP用戶只需要提供一個網關地址。與IP地址一樣,網關的IP地址可以靜態地配置爲FreeRTOS_IPInit()的參數,也可以從DHCP服務器動態地配置。

TCP:

以太網包可以攜帶IP包,而IP包又可以攜帶TCP包。

TCP代表傳輸控制協議。TCP用於在預先建立的連接上發送和接收數據流。TCP協議本身負責建立連接,並確保正確接收所有傳輸的數據。

TCP比UDP更可靠,但使用起來更復雜,且需要更多的內存。額外RAM的使用,一部分是因爲在數據包被確認正確發送到網絡前,需要保留這些已經發送到網絡的數據包。

MSS:

MSS代表最大段大小。它定義了在TCP或UDP包中可以發送或接收的最大數據量。它與MTU值的不同之處在於,它的值只適用於數據大小,而不適用於幀大小。因此MSS排除了以太網、IP、TCP或UDP協議頭。MSS取決於MTU和最大選項字節數。

下面是一個從1526字節的MTU開始的MSS計算示例。幀內包含的各個header消耗的字節數被減去,得到MSS大小:

1526  MTU size
 -14  Ethernet header size
 -20  IP protocol header size
 -20  TCP protocol header size
 -12  TCP options bytes
----
1460  MSS size

在FreeRTOS+TCP中,MSS值由FreeRTOSIPConfig.h中的ipconfigTCP_MSS設置。如果ipconfigTCP_MSS沒有定義,那麼它將被設置爲默認值1460。

在上面的例子中,計算出的MSS值爲1460字節,這對於局域網(LAN)是合適的,但是對於Internet來說可能太大了,爲了最大的可靠性,MSS應該限制在1400字節。因此,如果遠程節點的IP地址在本地網絡之外(請參閱netmask), FreeRTOS+TCP將自動將MSS設置爲1400或配置的ipconfigTCP_MSS值的最小值。

端口號(Port Number:

每個單獨的網絡節點可以運行多個使用相同網絡接口的應用程序,因此可以使用相同的IP地址。例如,RTOS應用程序可以同時運行TFTP服務器、echo服務器和Nabto客戶機 - 所有這些都使用了TCP/IP協議棧。因此在使用相同的IP地址的情況下,運行在相同網絡節點的不同應用程序通過它們的端口號加以區別。

因此,每個TCP或UDP數據包的源地址和目標地址是通過IP地址和端口號組合的。IP地址標識網絡上的節點,而端口號標識節點內的應用程序(參見sockets)。

網絡套接字(Network Sockets:

套接字在概念上是通信的端點( end point ),而Berkeley sockets API實際上是用於創建、配置、讀寫和管理套接字的跨平臺標準API。

套接字是用網絡節點的IP地址和端口號來標識的。

如果一個網絡節點想要向網絡發送UDP數據,它首先創建一個套接字,然後將數據發送到該套接字。如果一個網絡節點想要接收UDP數據,它首先在發送數據的節點所知道的地址上創建一個套接字,然後從該套接字讀取數據。

如果一個網絡節點希望向網絡發送TCP數據,它首先創建一個套接字,將該套接字連接到遠程節點上的一個套接字,然後將數據發送到該套接字。如果一個網絡節點想要接收TCP數據,首先要創建一個套接字,然後監聽套接字上的傳入連接。當接收到連接時,它可以(可選地)創建一個新的套接字來處理連接,然後接收新套接字上的數據——這樣可以讓原來的套接字繼續偵聽額外的傳入連接。

由此可以看出,任何一個網絡節點都可以同時參與多個網絡會話( network conversations)——每個唯一會話的每一端都使用一個套接字。

套接字還可以用來發送和接收廣播和多播通信——它們都是一對多通信的一種形式。

API函數FreeRTOS_socket()用於創建套接字。

綁定 Binding:

如前所述,每個套接字需要一個唯一的地址,地址是IP地址和端口號的組合。

在創建套接字時,它假定已經創建了它的網絡節點的IP地址。如果一個套接字有一個IP地址,但沒有端口號,則稱爲“未綁定”。未綁定的套接字無法接收數據,因爲它沒有完整的地址。

當一個套接字同時具有一個IP地址和一個端口號時,它被稱爲“綁定到一個端口”或“綁定到一個地址”。綁定套接字可以接收數據,因爲它有一個完整的地址。

API函數FreeRTOS_bind()用於將FreeRTOS+TCP套接字綁定到端口號。

如果在FreeRTOSIPConfig.h中將ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND設置爲0,那麼必須使用FreeRTOS_bind()將套接字綁定到端口號,然後才能使用套接字發送或接收數據。如果在FreeRTOSIPConfig.h的 ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND設置爲1一個未綁定套接字將自動綁定到一個端口號它試圖第一次發送數據(用於UDP套接字)或連接(用於TCP套接字),但是仍然可以只接收數據後綁定。

客戶機 Client:

客戶機是主動連接到遠程應用程序以從遠程應用程序獲得服務的應用程序。遠程應用程序是服務器。

服務器 Server

服務器是等待並回復來自客戶端的請求的應用程序。

客戶端需要定位服務器,實現這一點的最簡單方法是將服務器綁定到預先約定的地址(還有其他更復雜的方法)。

服務器不需要提前知道客戶的地址,它們只需要將它們的回覆發送到客戶請求發出的地址。因此,,儘管從0xC000到0xFFFF範圍內的高端口號是爲FreeRTOS+TCP本身保留的,同時許多低端口號(僅根據協定來看)是爲公共網絡業務(network)保留的,但是通常客戶端可以綁定到幾乎任何端口號。

靜態IP地址

已經注意到,每個網絡節點都有一個IP地址。如果IP地址是“靜態的”,那麼它是預先分配的,不會改變。

FreeRTOS+TCP API函數FreeRTOS_IPInit()接受一個默認的IP地址(在其他地址中)作爲參數之一。如果將ipconfigUSE_DHCP設置爲0,或者將ipconfigUSE_DHCP設置爲1,但是無法聯繫DHCP服務器,則使用默認的IP地址作爲靜態IP地址。

DHCP

DHCP代表動態主機控制協議( Dynamic Host Control Protocol.)。

靜態IP地址在應用程序開發期間是有用的,但對於產品部署來說是不切實際的,因爲:

  • 它們需要硬編碼到可執行的二進制文件或外部閃存中。
  • 如果不事先了解產品部署的網絡環境,就不能將IP地址預先分配給產品。
  • 我們不知道網絡上將存在多少節點,也不知道在任何時刻可能有多少節點處於活動狀態。

DHCP爲靜態IP地址分配提供了另一種選擇。DHCP服務器存在於本地網絡上,動態地將IP地址分配給同一網絡上的節點。當一個啓用了網絡的產品啓動時,它會聯繫DHCP服務器請求它的IP地址,這樣就不需要對每個節點進行靜態配置。

如果在FreeRTOSIPConfig.h中將ipconfigUSE_DHCP設置爲1,那麼FreeRTOS+TCP將嘗試從DHCP服務器獲取其IP地址,並且只有在無法聯繫到DHCP服務器時才恢復使用靜態IP地址(AutoIP也在路線圖中)。

運行FreeRTOS+TCP的設備可以向DHCP服務器註冊它的主機名。有關更多信息,請參見ipconfigDHCP_REGISTER_HOSTNAME配置常量。

專家用戶可以使用應用程序DHCP鉤子(或“回調”)函數來影響DHCP進程。

網絡名稱解析 Network Name Resolution

使用原始IP地址對遠程節點尋址並不總是可行的,因爲:

  • IP地址可以改變。
  • 遠程計算機的IP地址可能不知道。
  • IP地址不是很好記。

使用人類可讀的名稱來定位遠程節點更爲方便。將人類可讀(注:即英文或漢字,但不是不易記憶的數字)的名稱轉換爲IP地址的過程稱爲名稱解析。FreeRTOS+TCP可實現DNS, LLMNR和NBNS的功能,從而達到網絡域名解析的目的。

 

DNS:

DNS代表域名系統( Domain Name System),是域名解析的一種形式。

dns將靜態且易於人類閱讀的文本(而非數字)名稱映射到IP地址。域名服務器將文本域名解析爲適當的IP地址。例如,進入“ping www.freertos.org ”命令控制檯的臺式電腦將顯示一個ping請求被髮送到IP地址195.8.66.1(在撰寫本文時,IP地址可能會改變)因爲一個DNS服務器解決了IP地址195.8.66.1字符串“www.freertos.org”。

如果在FreeRTOSIPConfig.h中將ipconfigUSE_DNS設置爲1,那麼FreeRTOS+TCP API函數FreeRTOS_gethostbyname()可用於將文本名稱解析爲IP地址。

與運行FreeRTOS+TCP的節點的IP地址一樣,可以將域名服務器的IP地址靜態地配置爲FreeRTOS_IPInit()的參數,也可以從DHCP服務器動態地配置。

 

LLMNR:

LLMNR代表鏈接本地多播名稱解析( Link Local Multicast Name Resolution),這是一種用於名稱解析的協議。

LLMNR是一種在局域網中使用的多播協議。它是所有主要web瀏覽器用於解析不包含點(' . ')的名稱的方法。例如,如果嘗試打開web頁面 :http://my_freertos_device/index.html  (注:例子中的鏈接無法打開)。然後,web瀏覽器將發送一個LLMNR請求,嘗試並解析名稱“my_freertos_device”。

所有LLMNR包都被髮送到MAC地址01:00:5E:00:00:FC上的IP地址224.0.0.252,因此必須對網絡接口(MAC)進行編程,以接受該地址上的包,以便LLMNR發揮作用。另外,必須在FreeRTOSIPConfig中將ipconfigUSE_LLMNR定義爲1。用戶必須提供回調函數xApplicationDNSQueryHook()的實現,該函數接受一個char指針作爲參數,如果傳入函數的名稱與用於標識節點的名稱匹配,則返回pdTRUE。

注:這個解釋的不太容易懂,可見百度百科[2]

NBNS:

NBNS(有時稱爲WINS)代表NetBIO名稱服務(NetBIO Name Service),這是一個用於名稱解析的協議。

NBNS執行與LLMNR相同的功能,但是使用UDP廣播包而不是多播包。瀏覽器通常在嘗試使用LLMNR失敗後才嘗試使用nbn。

要啓用NBNS,必須將FreeRTOSIPConfig.h中的ipconfigUSE_NBNS設置爲1。與LLMNR一樣,應用程序編寫器必須提供xApplicationDNSQueryHook()回調函數,該函數接受字符指針作爲參數,如果傳遞給函數的名稱與用於的名稱匹配,則返回pdTRUE

大小端模式 Little Endian, Big Endian

不同的mcu以不同的方式存儲多字節值,比如兩個字節的uint16_t或四個字節的uint32_t。首先存儲最重要字節的微控制器稱爲大端字節控制器。首先存儲最低有效字節的微控制器稱爲小端字節控制器。運行FreeRTOS+TCP的MCU上存儲字節的方式稱爲主機字節順序(host byte order)。

編寫非連接應用程序的人很少需要關心他們的目標MCU如何在內部存儲數據。如果數據是以小端序寫入內存的,那麼它將以小端序從內存中讀取回來——因此,讀取回來的值將與最初寫入的值匹配。

連接mcu時,情況會更復雜,因爲不能保證連接網絡上的所有mcu具有相同的字節順序。網絡上的所有mcu必須事先同意用於發送和接收數據的字節順序。用於傳輸數據的字節順序稱爲網絡字節順序(network byte order)。

在TCP/IP網絡中,數據是先發送最重要的字節,這使得TCP/IP網絡有效地實現了大端口號。因此,一個小端字節序單片機發送TCP / IP網絡必須交換字節的順序出現在多字節值前的值發送到網絡上,並且必須交換字節的順序出現在多字節值從網絡接收之前所使用的值。一個大端字節控制器不需要執行任何字節交換,因爲MCU的端字節(主機字節順序)匹配網絡的約定端字節(網絡字節順序)。

注意:字節交換是由TCP/IP棧執行的——用戶不需要手動交換字節。

參考資料

[1] https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

[2] https://baike.baidu.com/item/LLMNR/1116392?fr=aladdin

[3] https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html

 

發佈了25 篇原創文章 · 獲贊 5 · 訪問量 8203
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章