【Linux網絡】:UDP(傳輸層協議)

目錄

一、鋪墊知識

1、傳輸層

2、端口號

?2.1、五元組表示 一個進程通信

2.2、端口號范圍劃分

2.3、知名端口

2.4、查看端口號

2.5、問題?

3、pidof & netstat 命令?

①netsate 命令

②pidof命令?

二、UDP協議

1、UDP協議格式

2、UDP報文

1.1、UDP數據封裝的過程

1.2、UDP數據交付的過程

3、UDP特點

3.1、面向數據報

4、UDP緩沖區

5、UDP傳輸最大長度

6、基于UDP的應用層協議

一、鋪墊知識

1、傳輸層

?通過HTTP/HTTPS的學習,對應用層有了一定的認識,接下來就是下一層協議:傳輸層協議。

兩臺計算機通過TCP/IP協議通訊的大致過程如下:

中間的傳輸層和網絡層是在內核實現的,而應用層是在用戶層實現的,這也就注定了在進行學習傳輸層的時候必然就是要學習在Linux內核中的關于網絡的部分,實際上傳輸層在操作系統的內部是提供了一套對應的系統調用,然后進行正常的數據讀取,那對于這部分系統調用也有很多的接口,比如在創建套接字的時候有listen,bind,receive這樣的接口,所以下一步要學習的內容就在傳輸層當中。

2、端口號

在學傳輸層前,先談談端口號,對于端口號的話題在之前已經學習過了,這里只是想說對于端口號的認識,作為一臺主機來說,服務器可能會有很多的應用服務,每一個應用服務都要綁定一個明確的端口號,那這個端口號的意義就是能夠保證讓數據傳輸給上面的那一個應用程序,因為對于進程的區分就可以借助這個端口號來進行區分,借助ip地址和端口號就可以做到在全網找到唯一的一臺主機,而從這個主機上找到唯一的一個進程,這樣就能精確的找到對應的網絡服務了。

?2.1、五元組表示 一個進程通信

在?TCP/IP?協議中,用?“源IP”,“源端口號”,“目的?IP”,“目的端口號”,“協議號”?這樣一個五元組來標識一個通信。?舉例:打開瀏覽器后,添加多個同賬戶頁面訪問 CSDN,雖然源 IP 地址是一樣的,但是源端口號不同,就表示兩個不同的通信。通過這個五元組,服務器能夠準確的區分請求是從哪里來的。

所以現在我們可以大致的清楚通信的流程:

  1. 先提取出數據當中的目的 IP 地址目的端口號,確定該數據是發送給當前服務進程的。
  2. 然后提取出數據當中的協議號,為該數據提供對應類型的服務。
  3. 最后提取出數據當中的源 IP 地址源端口號,將其作為響應數據的目的 IP 地址和目的端口號,將響應結果發送給對應的客戶端進程。

2.2、端口號范圍劃分

端口號是一個 16 位的整數,它的取值范圍是 0~65535。

  • 0~1023:知名端口號。比如 HTTP,FTP,SSH 等這些廣為使用的應用層協議,它們的端口號都是固定的。(類比 120 或 110)
  • 1024~65535:操作系統動態分配的端口號。客戶端程序的端口號就是由操作系統從這個范圍分配的,允許用戶手動綁定。

2.3、知名端口

有些服務器是非常常用的,為了使用方便,人們約定一些常用的服務器,都是用以下這些固定的端口號:

  • ssh 服務器使用 22 端口
  • ftp 服務器使用 21 端口
  • telnet 服務器使用 23 端口
  • http 服務器使用 80 端口
  • https 服務器使用 443

2.4、查看端口號

可以通過命令 vim /etc/services 查看文件內容,該文件是記錄網絡服務名和它們對應使用的端口號及協議。當自己寫一個程序使用端口號時,要避開這些知名端口號。

2.5、問題?

一個進程可不可以?bind 多個端口號?

可以。假設綁定了兩個端口號 A 和 B,這兩個端口號標識的是同一個進程 ,這與端口號用來標識進程的唯一性并不沖突。

一個端口號是否可以被多個進程 bind?

不行,因為端口號的作用就是標識唯一的一個進程。

如果綁定了多個進程,如何找到對應的進程呢?所以如果綁定一個已經被綁定的端口號就會出現綁定失敗的問題。

3、pidof & netstat 命令?

①netsate 命令

netstat?是一個用來查看網絡狀態的重要工具。

sudo netstat -ntlp? 查看TCP相關網絡信息

sudo netstat -nulp 查看UDP相關網絡信息

  • n:拒絕顯示別名,能顯示數字的全部轉化成數字。
  • l:僅列出有在 Listen(監聽)的服務狀態。
  • p:顯示建立相關鏈接的程序名(進程:process)。
  • t(tcp):僅顯示 tcp 相關選項。
  • u(udp):僅顯示 udp 相關選項。
  • a(all):顯示所有選項,默認不顯示 LISTEN 相關。

②pidof命令?

通過進程名來查看服務器進程的 pid。

ps axj | grep UdpServer

pidof UdpServer

二、UDP協議

學習傳輸層的協議,要從UDP協議入手,其中一個原因是UDP協議還是相對簡單一些。

任何協議進行封裝后都要進行解包,那如何辨別有效載荷和報頭呢?

對于這個問題在自定義協議當中,我們采取的策略是使用了一個\n來進行標記,在前面也有對應的字符串長度來進行解析,而在http協議中采用的方案是用了空行來進行對應的分割工作,那在UDP當中呢?如下:

1、UDP協議格式

  • 16 位源端口號:表示數據從哪里來。
  • 16 位目的端口號:表示數據要到哪里去。
  • 16 位 UDP 長度:表示整個數據報(UDP 首部 + UDP 數據)的最大長度。
  • 16 位 UDP 檢驗和:如果UDP報文的檢驗和出錯,就會直接將報文丟棄。

UDP的定義十分簡單粗暴,就是一個定長報頭,規定前面的這些字段就是定長的,規定前8個字節就是報頭,剩下的部分就是有效載荷

為什么我們前面在應用層編寫代碼的時候,每一次寫端口號都喜歡用?uint16_t 呢?

其根本原因就是因為傳輸層協議中的端口號就是 16 位的。

send 數據并不是直接發送到網絡里,而是發給了傳輸層。然后傳輸層再通過網絡協議棧繼續發送。那接收端如何將報頭和有效載荷進行分離?

UDP 采用的是固定報頭,UDP 的報頭中只包含四個字段,每個字段的長度都是 16 位,總共 8 字節,所以直接提取前 8 個字節就是報頭,其他的就是有效載荷。UDP 具有將報文一個個正確接收的能力,UDP 是面向數據報的。

UDP 如何交付?(有效載荷交給上層的哪一個協議?)

應用層每個進程都綁定有端口號,UDP 就是通過報頭當中的目的端口號來找到對應的應用層進程的,把有效載荷交出去。

2、UDP報文

這里的報頭其實就是一種結構化數據對象(位段):

struct udp_hdr
{uint16_t src_port;  // 源端口uint16_t dsc_port;  // 目的端口uint16_t udp_len;   // UDP長度uint16_t udp_check; // 校驗和
};

這個結構體中的內容其實都與上面的圖中所示的報頭字段一一對應,而實際上對于UDP的報頭理解確實可以理解為是對于UDP的字段填充的過程。?

1.1、UDP數據封裝的過程

那么如果要是使用UDP協議向網絡中發送Hello World這樣的字段,該如何理解這個過程呢?
首先要知道應用層 sendto 數據是發給傳輸層的。

創建一塊內存,計算出有效載荷的起始地址,拷貝有效載荷,強轉填寫報頭部分,最后形成 UDP 報文。

操作系統會提供一個類似于緩沖區的這樣的一段區域,那在這個緩沖區中就會構建對應的UDP請求,未來都是會在這個地方通過操作系統向對方發送UDP對應的報文,那這段UDP的報文會在內核中進行流動,它未來是要向下交互到底層硬件進行發送的,這就必然意味著在操作系統的內部會存在很多的UDP的報文

站在接收方的角度來講,未來它也會受到大量的UDP的報文,所以操作系統必然要對于這么多的UDP報文進行管理,因此在操作系統內部會存在這個叫做sk_buff的結構體

在這個結構體中會有對應的start,end,pos指針,那當未來要構建一個UDP的報文,在內核的層面上就會定義一段緩沖區,之后把前面定義的報頭部分拷貝進來,然后再把用戶空間的Hello World拷貝進來,然后把對應的start,end,pos這樣的指針進行一個描述,這樣對于當前UDP的報文就管理起來了,之后在內核中可以使用鏈表,來把這一個一個的UDP報文進行鏈接管理起來,這樣就能實現對于內核中UDP報文的管理工作

至此,UDP的傳輸原理其實就是這樣,雖然在內核中的實際實現并不是這樣,但是基本思想確實如此,未來有機會再對于源碼中的UDP部分進行分析詳解。

1.2、UDP數據交付的過程

因為是定長報頭,直接取出目的端口號,把有效載荷向上交付給指定協議(進程)。

3、UDP特點

UDP?傳輸的過程類似于寄信。

  • 無連接:知道對端的 IP 和端口號就直接進行傳輸,不需要建立連接。
  • 不可靠:沒有確認機制,沒有重傳機制。如果因為網絡故障該段無法發到對方,UDP 協議層也不會給應用層返回任何錯誤信息。
  • 面向數據報:不能夠靈活的控制讀寫數據的次數和數量。要讀取就必須讀取一個完整的報文。

3.1、面向數據報

舉例理解:別人發了三個快遞,那么我們就一定要收到三個,不會出現只收到一個,一個半這樣的情況。如果只有一個包裹,那我們也不能只拿走一半。結論:發送了一個報文,要么不讀,要么 recvfrom 等到讀取完一整個報文再返回。

應用層交給 UDP 多長的報文,UDP 原樣發送,既不會拆分,也不會合并。

用 UDP 傳輸 100 個字節的數據:如果發送端調用一次 sendto,發送 100 字節,那么接收端也必須調用對應的一次recvfrom,接收100個字節;而不能循環調用10次recvfrom,每次接收10個字節。

4、UDP緩沖區

嚴格意義上來說:

  • UDP?沒有真正意義上的發送緩沖區。因為它沒有可靠機制,不需要把數據暫存起來。它直接調用 sendto 會直接交給內核,由內核將數據傳給網絡層協議進行后續的傳輸動作。
  • UDP 是只有接收緩沖區。這個緩沖區是用來保存用戶暫時來不及處理的報文,但是這個接收緩沖區不能保證收到的 UDP 報的順序和發送 UDP 報的順序一致,如果緩沖區滿了,再到達的 UDP 數據就會被丟棄。

UDP 的 socket 既能讀,也能寫,所以是全雙工的。

為什么 UDP 要有緩沖區?

如果 UDP 沒有接收緩沖區,那么就要求上層及時將 UDP 獲取到的報文讀取上去,如果一個報文在 UDP 沒有被讀取,那么此時 UDP 從底層獲取上來的報文數據就會被迫丟棄。

5、UDP傳輸最大長度

UDP?協議首部中有一個?16?位的最大長度,因此一個 UDP 能傳輸的數據最大長度是?64K(包含 UDP 報頭的大小)。

然而 64K?在當今的互聯網環境下是一個非常小的數字,如果我們要傳輸的數據大于 64K,就需要在應用層進行手動分包,多次發送并在接收端進行手動拼裝。

6、基于UDP的應用層協議

  • NFS:網絡文件系統
  • TFTP:簡單文件傳輸協議
  • DHCP:動態主機配置協議
  • BOOTP:啟動協議(用于無盤設備啟動)
  • DNS:域名解析協議

當然也包括我們自己寫?UDP?程序時自定義的應用層協議。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91725.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91725.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91725.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Effective C++ 條款19: 設計class猶如設計type

Effective C 條款19:設計class猶如設計type核心思想:設計新的class時,應當像語言設計者設計內置類型一樣慎重,考慮對象的創建、銷毀、初始化、拷貝、類型轉換等所有方面。 ?? 1. 類設計的關鍵問題域 對象生命周期管理&#xff1…

《匯編語言:基于X86處理器》第11章 MS-Windows編程(3)

本章展示的是如何用32 位Microsoft Windows API進行控制臺窗口編程。應用編程接口(API:ApplicationProgramming Interface)是類型、常數和函數的集合體,它提供了一種用計算機代碼操作對象的方式。本章將討論文本I/O、顏色選擇、時間與日期、數據文件I/O,…

在 macOS 上通過 Docker 部署DM8 (ARM 架構)

概述 達夢數據庫 (DM8) 無法直接在 Apple macOS 操作系統上原生安裝,通常需要通過虛擬機(如 Parallels Desktop、VMware Fusion)進行部署。另一種更輕量級且受 macOS 支持的方案是利用 Docker 容器技術來構建開發與測試環境。本文檔將詳細介…

網絡協議之路由是怎么回事?

寫在前面 要想去外面的世界看看, 就離不了路由器,而路由器工作的原理就是路由,那么具體是怎么路由的呢?本文就一起來看下這部分內容。 1:路由的配置 配置一條路由無非就是在配置以下三個信息: 1:包要去哪里&#x…

2106. 摘水果,梳理思路

文章目錄題目概要java 解法詳解題目概要 在一個無限的 x 坐標軸上,有許多水果分布在其中某些位置。給你一個二維整數數組 fruits ,其中 fruits[i] [positioni, amounti] 表示共有 amounti 個水果放置在 positioni 上。fruits 已經按 positioni 升序排列…

深入理解消息隊列(MQ)核心原理與設計精髓

引言:從一個“不堪重負”的訂單系統說起想象一個簡化的電商下單流程:用戶點擊“下單”后,系統需要:在訂單數據庫中創建一條記錄。調用庫存服務,扣減商品庫存。調用營銷服務,給用戶發放積分和優惠券。調用通…

前端手撕題總結篇(算法篇——來自Leetcode牛客)

鏈表指定區域反轉 找到區間(頭和為 for循環當**時)->反轉鏈表(返回反轉過后的頭和尾)->連接 function reverseBetween( head , m , n ) {//preEnd&cur&nextStart cur.next斷開if(mn)return head;const vHeadNode…

從Excel到工時管理系統:企業如何選擇更高效的工時記錄工具?

還在為手工統計員工工時而頭疼嗎?月末堆積如山的Excel表格、反復核對的數據、層出不窮的差錯,這些問題正在拖慢企業的發展步伐。8Manage工時管理系統發現,傳統手工記錄不僅耗費大量人力,更讓寶貴的工時數據難以轉化為有效的管理決…

Java設計模式之《命令模式》

目錄 1、介紹 1.1、命令模式定義 1.2、對比 1.3、典型應用場景 2、命令模式的結構 2.1、組成部分: 2.2、整體流程 3、實現 3.1、沒有命令模式 3.2、命令模式寫法 4、命令模式的優缺點 前言 java設計模式分類: 1、介紹 1.1、命令模式定義 命…

【動態規劃算法】路徑問題

什么是動態規劃算法動態規劃(Dynamic Programming,簡稱 DP)是一種通過分解復雜問題為重疊子問題,并存儲子問題的解以避免重復計算,從而高效求解具有特定性質(重疊子問題、最優子結構)問題的算法…

Java基本技術講解

一、基礎語法三要素 暫時無法在飛書文檔外展示此內容 🔑 黃金法則?:每個變量都要聲明類型!二、程序邏輯控制(游戲行為核心) 條件判斷:if-else - “岔路口選擇” // 撿到金幣邏輯 if (isTouching(Coin.clas…

【網絡基礎2】路由器的 “兩扇門”:二層接口和三層接口到底有啥不一樣?

目錄 前言:路由器不是只有 “插網線的口” 一、先搞懂一個基礎:路由器是 “網絡交通樞紐” 二、二層接口:“小區內部的單元門”,只認 “住戶身份證” 1. 啥是二層接口? 2. 用 “小區內部串門” 理解二層接口 步驟 1:手機打包數據,寫上 “收件人身份證” 步驟 2:二…

MLIR TableGen

簡介 TableGen 是一種領域特定語言(DSL),TableGen 的設計目標是允許編寫靈活的描述,并將記錄的通用特性提取出來,從而減少重復代碼并提高代碼的可維護性。 TableGen的工作流程: 前端解析: Ta…

2、docker容器命令 | 信息查看

1、命令總覽命令作用docker ps查看運行中的容器(-a查看所有容器)docker logs [CONTAINER]查看容器日志(-f實時追蹤日志)docker inspect [CONTAINER]查看容器詳細信息(JSON格式)docker stats [CONTAINER]實時…

【MySQL】MySQL中鎖有哪些?

一、按照粒度分類: 粒度越小,并發度越高,鎖開銷越大。 1.全局鎖: 作用: 鎖定整個MySQL實例(所有數據庫)。適用場景: 全庫邏輯部分。(確保備份期間數據的一致性。)實現方式: 通過 FLUSH TABLES W…

語義分割--deeplabV3+

根據論文網絡結構圖講一下:網絡分為兩部分:encoder和decoder部分。 Encoder:DCNN就是主干網絡,例如resnet,Xception,MobileNet這些(主干網絡也要使用空洞卷積),對dcnn的結…

Azure DevOps 中的代理

必知詞匯 深入研究 Azure DevOps 中的代理之前需要掌握的基本概念: 代理:Azure DevOps 中的代理是一個軟件組件,負責執行流水線中的任務和作業。這可能包括數據中心內的物理服務器、本地或云端托管的虛擬機,甚至是容器化環境。這些代理可以在各種操作系統和環境中運行,例如…

AUTOSAR進階圖解==>AUTOSAR_SRS_ADCDriver

AUTOSAR ADC驅動詳解 基于AUTOSAR標準的ADC驅動模塊需求規范分析目錄 ADC驅動模塊概述 關鍵概念定義 ADC驅動架構 ADC驅動在AUTOSAR分層架構中的位置ADC驅動的主要職責 ADC驅動配置結構 通用配置(AdcGeneral)硬件單元配置(AdcHwUnit)通道配置(AdcChannel)通道組配置(AdcChanne…

寶馬集團與SAP聯合打造生產物流數字化新標桿

在德國雷根斯堡的寶馬工廠,每57秒就有一輛新車下線。這座工廠不僅是汽車制造的基地,更是寶馬集團向SAP S/4HANA云平臺轉型的先鋒項目。通過“RISE with SAP”計劃,寶馬將該工廠的運營系統全面遷移至SAP S/4HANA Cloud Private Edition&#x…

Go 語言實戰:構建一個高性能的 MySQL + Redis 應用

引言:為什么是 Go MySQL Redis?在現代后端技術棧中,Go MySQL Redis 的組合堪稱“黃金搭檔”,被廣泛應用于各種高并發業務場景。Go 語言:以其卓越的并發性能、簡潔的語法和高效的執行效率,成為構建高性能…