www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]拿下計(jì)網(wǎng)協(xié)議后,我就是公園里最靚的仔!

前言

拿下計(jì)網(wǎng)協(xié)議后,我就是公園里最靚的仔

TCP/IP 基礎(chǔ)知識(shí)總結(jié)

計(jì)算機(jī)網(wǎng)絡(luò)基礎(chǔ)知識(shí)總結(jié)

那么下面就開(kāi)始我們本篇文章,文章組織脈絡(luò)如下

40張圖帶你搞懂TCP和UDP

運(yùn)輸層位于應(yīng)用層和網(wǎng)絡(luò)層之間,是 OSI 分層體系中的第四層,同時(shí)也是網(wǎng)絡(luò)體系結(jié)構(gòu)的重要部分。運(yùn)輸層主要負(fù)責(zé)網(wǎng)絡(luò)上的端到端通信。

40張圖帶你搞懂TCP和UDP

運(yùn)輸層為運(yùn)行在不同主機(jī)上的應(yīng)用程序之間的通信起著至關(guān)重要的作用。下面我們就來(lái)一起探討一下關(guān)于運(yùn)輸層的協(xié)議部分

運(yùn)輸層概述

計(jì)算機(jī)網(wǎng)絡(luò)的運(yùn)輸層非常類(lèi)似于高速公路,高速公路負(fù)責(zé)把人或者物品從一端運(yùn)送到另一端,而計(jì)算機(jī)網(wǎng)絡(luò)的運(yùn)輸層則負(fù)責(zé)把報(bào)文從一端運(yùn)輸?shù)搅硪欢?,這個(gè)端指的就是?端系統(tǒng)。在計(jì)算機(jī)網(wǎng)絡(luò)中,任意一個(gè)可以交換信息的介質(zhì)都可以稱(chēng)為端系統(tǒng),比如手機(jī)、網(wǎng)絡(luò)媒體、電腦、運(yùn)營(yíng)商等。

在運(yùn)輸層運(yùn)輸報(bào)文的過(guò)程中,會(huì)遵守一定的協(xié)議規(guī)范,比如一次傳輸?shù)臄?shù)據(jù)限制、選擇什么樣的運(yùn)輸協(xié)議等。運(yùn)輸層實(shí)現(xiàn)了讓兩個(gè)互不相關(guān)的主機(jī)進(jìn)行邏輯通信的功能,看起來(lái)像是讓兩個(gè)主機(jī)相連一樣。

運(yùn)輸層協(xié)議是在端系統(tǒng)中實(shí)現(xiàn)的,而不是在路由器中實(shí)現(xiàn)的。路由只是做識(shí)別地址并轉(zhuǎn)發(fā)的功能。這就比如快遞員送快遞一樣,當(dāng)然是要由地址的接受人也就是 xxx 號(hào)樓 xxx 單元 xxx 室的這個(gè)人來(lái)判斷了!

40張圖帶你搞懂TCP和UDP

TCP 如何判斷是哪個(gè)端口的呢?

還記得數(shù)據(jù)包的結(jié)構(gòu)嗎,這里來(lái)回顧一下

40張圖帶你搞懂TCP和UDP

數(shù)據(jù)包經(jīng)過(guò)每層后,該層協(xié)議都會(huì)在數(shù)據(jù)包附上包首部,一個(gè)完整的包首部圖如上所示。

在數(shù)據(jù)傳輸?shù)竭\(yùn)輸層后,會(huì)為其附上 TCP 首部,首部包含著源端口號(hào)和目的端口號(hào)。

在發(fā)送端,運(yùn)輸層將從發(fā)送應(yīng)用程序進(jìn)程接收到的報(bào)文轉(zhuǎn)化成運(yùn)輸層分組,分組在計(jì)算機(jī)網(wǎng)絡(luò)中也稱(chēng)為?報(bào)文段(segment)。運(yùn)輸層一般會(huì)將報(bào)文段進(jìn)行分割,分割成為較小的塊,為每一塊加上運(yùn)輸層首部并將其向目的地發(fā)送。

在發(fā)送過(guò)程中,可選的運(yùn)輸層協(xié)議(也就是交通工具) 主要有?TCP?和?UDP?,關(guān)于這兩種運(yùn)輸協(xié)議的選擇及其特性也是我們著重探討的重點(diǎn)。

TCP 和 UDP 前置知識(shí)

在 TCP/IP 協(xié)議中能夠?qū)崿F(xiàn)傳輸層功能的,最具代表性的就是 TCP 和 UDP。提起 TCP 和 UDP ,就得先從這兩個(gè)協(xié)議的定義說(shuō)起。

TCP 叫做傳輸控制協(xié)議(TCP,Transmission Control Protocol),通過(guò)名稱(chēng)可以大致知道 TCP 協(xié)議有控制傳輸?shù)墓δ?,主要體現(xiàn)在其可控,可控就表示著可靠,確實(shí)是這樣的,TCP 為應(yīng)用層提供了一種可靠的、面向連接的服務(wù),它能夠?qū)⒎纸M可靠的傳輸?shù)椒?wù)端。

UDP 叫做?用戶(hù)數(shù)據(jù)報(bào)協(xié)議(UDP,User Datagram Protocol),通過(guò)名稱(chēng)可以知道 UDP 把重點(diǎn)放在了數(shù)據(jù)報(bào)上,它為應(yīng)用層提供了一種無(wú)需建立連接就可以直接發(fā)送數(shù)據(jù)報(bào)的方法。

怎么計(jì)算機(jī)網(wǎng)絡(luò)中的術(shù)語(yǔ)對(duì)一個(gè)數(shù)據(jù)的描述這么多???

在計(jì)算機(jī)網(wǎng)絡(luò)中,在不同層之間會(huì)有不同的描述。我們上面提到會(huì)將運(yùn)輸層的分組稱(chēng)為報(bào)文段,除此之外,還會(huì)將 TCP 中的分組也稱(chēng)為報(bào)文段,然而將 UDP 的分組稱(chēng)為數(shù)據(jù)報(bào),同時(shí)也將網(wǎng)絡(luò)層的分組稱(chēng)為數(shù)據(jù)報(bào)

40張圖帶你搞懂TCP和UDP

但是為了統(tǒng)一,一般在計(jì)算機(jī)網(wǎng)絡(luò)中我們統(tǒng)一稱(chēng) TCP 和 UDP 的報(bào)文為?報(bào)文段,這個(gè)就相當(dāng)于是約定,到底如何稱(chēng)呼不用過(guò)多糾結(jié)啦。

套接字

在 TCP 或者 UDP 發(fā)送具體的報(bào)文信息前,需要先經(jīng)過(guò)一扇?門(mén),這個(gè)門(mén)就是套接字(socket),套接字向上連接著應(yīng)用層,向下連接著網(wǎng)絡(luò)層。在操作系統(tǒng)中,操作系統(tǒng)分別為應(yīng)用和硬件提供了接口(Application Programming Interface)。而在計(jì)算機(jī)網(wǎng)絡(luò)中,套接字同樣是一種接口,它也是有接口 API 的。

使用 TCP 或 UDP 通信時(shí),會(huì)廣泛用到套接字的 API,使用這套 API 設(shè)置 IP 地址、端口號(hào),實(shí)現(xiàn)數(shù)據(jù)的發(fā)送和接收。

40張圖帶你搞懂TCP和UDP

現(xiàn)在我們知道了, Socket 和 TCP/IP 沒(méi)有必然聯(lián)系,Socket 的出現(xiàn)只是方便了 TCP/IP 的使用,如何方便使用呢?你可以直接使用下面 Socket API 的這些方法。

40張圖帶你搞懂TCP和UDP

套接字類(lèi)型

套接字的主要類(lèi)型有三種,下面我們分別介紹一下

  • 數(shù)據(jù)報(bào)套接字(Datagram sockets):數(shù)據(jù)報(bào)套接字提供一種無(wú)連接的服務(wù),而且并不能保證數(shù)據(jù)傳輸?shù)目煽啃?。?shù)據(jù)有可能在傳輸過(guò)程中丟失或出現(xiàn)數(shù)據(jù)重復(fù),且無(wú)法保證順序地接收到數(shù)據(jù)。數(shù)據(jù)報(bào)套接字使用UDP( User DatagramProtocol)協(xié)議進(jìn)行數(shù)據(jù)的傳輸。由于數(shù)據(jù)報(bào)套接字不能保證數(shù)據(jù)傳輸?shù)目煽啃?,?duì)于有可能出現(xiàn)的數(shù)據(jù)丟失情況,需要在程序中做相應(yīng)的處理。

  • 流套接字(Stream sockets):流套接字用于提供面向連接、可靠的數(shù)據(jù)傳輸服務(wù)。能夠保證數(shù)據(jù)的可靠性、順序性。流套接字之所以能夠?qū)崿F(xiàn)可靠的數(shù)據(jù)服務(wù),原因在于其使用了傳輸控制協(xié)議,即?TCP(The Transmission Control Protocol)協(xié)議

  • 原始套接字(Raw sockets): 原始套接字允許直接發(fā)送和接收 IP 數(shù)據(jù)包,而無(wú)需任何特定于協(xié)議的傳輸層格式,原始套接字可以讀寫(xiě)內(nèi)核沒(méi)有處理過(guò)的 IP 數(shù)據(jù)包。

套接字處理過(guò)程

在計(jì)算機(jī)網(wǎng)絡(luò)中,要想實(shí)現(xiàn)通信,必須至少需要兩個(gè)端系統(tǒng),至少需要一對(duì)兩個(gè)套接字才行。下面是套接字的通信過(guò)程。

40張圖帶你搞懂TCP和UDP

  1. socket 中的 API 用于創(chuàng)建通信鏈路中的端點(diǎn),創(chuàng)建完成后,會(huì)返回描述該套接字的套接字描述符。

就像使用文件描述符來(lái)訪問(wèn)文件一樣,套接字描述符用來(lái)訪問(wèn)套接字。

  1. 當(dāng)應(yīng)用程序具有套接字描述符后,它可以將唯一的名稱(chēng)綁定在套接字上,服務(wù)器必須綁定一個(gè)名稱(chēng)才能在網(wǎng)絡(luò)中訪問(wèn)

  2. 在為服務(wù)端分配了 socket 并且將名稱(chēng)使用 bind 綁定到套接字上后,將會(huì)調(diào)用 listen api。listen?表示客戶(hù)端愿意等待連接的意愿,listen 必須在 accept api 之前調(diào)用。

  3. 客戶(hù)端應(yīng)用程序在流套接字(基于 TCP)上調(diào)用?connect?發(fā)起與服務(wù)器的連接請(qǐng)求。

  4. 服務(wù)器應(yīng)用程序使用acceptAPI 接受客戶(hù)端連接請(qǐng)求,服務(wù)器必須先成功調(diào)用 bind 和 listen 后,再調(diào)用 accept api。

  5. 在流套接字之間建立連接后,客戶(hù)端和服務(wù)器就可以發(fā)起 read/write api 調(diào)用了。

  6. 當(dāng)服務(wù)器或客戶(hù)端要停止操作時(shí),就會(huì)調(diào)用?close?API 釋放套接字獲取的所有系統(tǒng)資源。

雖然套接字 API 位于應(yīng)用程序?qū)雍蛡鬏攲又g的通信模型中,但是套接字 API 不屬于通信模型。套接字 API 允許應(yīng)用程序與傳輸層和網(wǎng)絡(luò)層進(jìn)行交互。

在往下繼續(xù)聊之前,我們先播放一個(gè)小插曲,簡(jiǎn)單聊一聊 IP。

聊聊 IP

IP?是Internet Protocol(網(wǎng)際互連協(xié)議)的縮寫(xiě),是 TCP/IP 體系中的網(wǎng)絡(luò)層協(xié)議。設(shè)計(jì) IP 的初衷主要想解決兩類(lèi)問(wèn)題

  • 提高網(wǎng)絡(luò)擴(kuò)展性:實(shí)現(xiàn)大規(guī)模網(wǎng)絡(luò)互聯(lián)

  • 對(duì)應(yīng)用層和鏈路層進(jìn)行解藕,讓二者獨(dú)立發(fā)展。

IP 是整個(gè) TCP/IP 協(xié)議族的核心,也是構(gòu)成互聯(lián)網(wǎng)的基礎(chǔ)。為了實(shí)現(xiàn)大規(guī)模網(wǎng)絡(luò)的互通互聯(lián),IP 更加注重適應(yīng)性、簡(jiǎn)潔性和可操作性,并在可靠性做了一定的犧牲。IP 不保證分組的交付時(shí)限和可靠性,所傳送分組有可能出現(xiàn)丟失、重復(fù)、延遲或亂序等問(wèn)題。

我們知道,TCP 協(xié)議的下一層就是 IP 協(xié)議層,既然 IP 不可靠,那么如何保證數(shù)據(jù)能夠準(zhǔn)確無(wú)誤地到達(dá)呢?

這就涉及到 TCP 傳輸機(jī)制的問(wèn)題了,我們后面聊到 TCP 的時(shí)候再說(shuō)。

端口號(hào)

在聊端口號(hào)前,先來(lái)聊一聊文件描述以及 socket 和端口號(hào)的關(guān)系

為了方便資源的使用,提高機(jī)器的性能、利用率和穩(wěn)定性等等原因,我們的計(jì)算機(jī)都有一層軟件叫做操作系統(tǒng),它用于幫我們管理計(jì)算機(jī)可以使用的資源,當(dāng)我們的程序要使用一個(gè)資源的時(shí)候,可以向操作系統(tǒng)申請(qǐng),再由操作系統(tǒng)為我們的程序分配和管理資源。通常當(dāng)我們要訪問(wèn)一個(gè)內(nèi)核設(shè)備或文件時(shí),程序可以調(diào)用系統(tǒng)函數(shù),系統(tǒng)就會(huì)為我們打開(kāi)設(shè)備或文件,然后返回一個(gè)文件描述符fd(或稱(chēng)為ID,是一個(gè)整數(shù)),我們要訪問(wèn)該設(shè)備或文件,只能通過(guò)該文件描述符??梢哉J(rèn)為該編號(hào)對(duì)應(yīng)著打開(kāi)的文件或設(shè)備。

而當(dāng)我們的程序要使用網(wǎng)絡(luò)時(shí),要使用到對(duì)應(yīng)的操作系統(tǒng)內(nèi)核的操作和網(wǎng)卡設(shè)備,所以我們可以向操作系統(tǒng)申請(qǐng),然后系統(tǒng)會(huì)為我們創(chuàng)建一個(gè)套接字 Socket,并返回這個(gè) Socket 的ID,以后我們的程序要使用網(wǎng)絡(luò)資源,只要向這個(gè) Socket 的編號(hào) ID 操作即可。而我們的每一個(gè)網(wǎng)絡(luò)通信的進(jìn)程至少對(duì)應(yīng)著一個(gè) Socket。向 Socket 的 ID 中寫(xiě)數(shù)據(jù),相當(dāng)于向網(wǎng)絡(luò)發(fā)送數(shù)據(jù),向 Socket 中讀數(shù)據(jù),相當(dāng)于接收數(shù)據(jù)。而且這些套接字都有唯一標(biāo)識(shí)符——文件描述符 fd。

端口號(hào)是?16?位的非負(fù)整數(shù),它的范圍是 0 - 65535 之間,這個(gè)范圍會(huì)分為三種不同的端口號(hào)段,由 Internet 號(hào)碼分配機(jī)構(gòu) IANA 進(jìn)行分配

  • 周知/標(biāo)準(zhǔn)端口號(hào),它的范圍是 0 - 1023

  • 注冊(cè)端口號(hào),范圍是 1024 - 49151

  • 私有端口號(hào),范圍是 49152 - 6553

一臺(tái)計(jì)算機(jī)上可以運(yùn)行多個(gè)應(yīng)用程序,當(dāng)一個(gè)報(bào)文段到達(dá)主機(jī)后,應(yīng)該傳輸給哪個(gè)應(yīng)用程序呢?你怎么知道這個(gè)報(bào)文段就是傳遞給 HTTP 服務(wù)器而不是 SSH 服務(wù)器的呢?

是憑借端口號(hào)嗎?當(dāng)報(bào)文到達(dá)服務(wù)器時(shí),是端口號(hào)來(lái)區(qū)分不同應(yīng)用程序的,所以應(yīng)該借助端口號(hào)來(lái)區(qū)分。

舉個(gè)例子反駁一下 cxuan,假如到達(dá)服務(wù)器的兩條數(shù)據(jù)都是由 80 端口發(fā)出的你該如何區(qū)分呢?或者說(shuō)到達(dá)服務(wù)器的兩條數(shù)據(jù)端口一樣,協(xié)議不同,該如何區(qū)分呢?

所以?xún)H憑端口號(hào)來(lái)確定某一條報(bào)文顯然是不夠的。

互聯(lián)網(wǎng)上一般使用?源 IP 地址、目標(biāo) IP 地址、源端口號(hào)、目標(biāo)端口號(hào)?來(lái)進(jìn)行區(qū)分。如果其中的某一項(xiàng)不同,就被認(rèn)為是不同的報(bào)文段。這些也是多路分解和多路復(fù)用?的基礎(chǔ)。

確定端口號(hào)

在實(shí)際通信之前,需要先確定一下端口號(hào),確定端口號(hào)的方法分為兩種:

  • 標(biāo)準(zhǔn)既定的端口號(hào)

標(biāo)準(zhǔn)既定的端口號(hào)是靜態(tài)分配的,每個(gè)程序都會(huì)有自己的端口號(hào),每個(gè)端口號(hào)都有不同的用途。端口號(hào)是一個(gè) 16 比特的數(shù),其大小在 0 - 65535 之間,0 - 1023 范圍內(nèi)的端口號(hào)都是動(dòng)態(tài)分配的既定端口號(hào),例如 HTTP 使用 80 端口來(lái)標(biāo)識(shí),F(xiàn)TP 使用 21 端口來(lái)標(biāo)識(shí),SSH 使用 22 來(lái)標(biāo)識(shí)。這類(lèi)端口號(hào)有一個(gè)特殊的名字,叫做?周知端口號(hào)(Well-Known Port Number)。

  • 時(shí)序分配的端口號(hào)

第二種分配端口號(hào)的方式是一種動(dòng)態(tài)分配法,在這種方法下,客戶(hù)端應(yīng)用程序可以完全不用自己設(shè)置端口號(hào),憑借操作系統(tǒng)進(jìn)行分配,操作系統(tǒng)可以為每個(gè)應(yīng)用程序分配互不沖突的端口號(hào)。這種動(dòng)態(tài)分配端口號(hào)的機(jī)制即使是同一個(gè)客戶(hù)端發(fā)起的 TCP 連接,也能識(shí)別不同的連接。

多路復(fù)用和多路分解

我們上面聊到了在主機(jī)上的每個(gè)套接字都會(huì)分配一個(gè)端口號(hào),當(dāng)報(bào)文段到達(dá)主機(jī)時(shí),運(yùn)輸層會(huì)檢查報(bào)文段中的目的端口號(hào),并將其定向到相應(yīng)的套接字,然后報(bào)文段中的數(shù)據(jù)通過(guò)套接字進(jìn)入其所連接的進(jìn)程。下面我們來(lái)聊一下什么是多路復(fù)用和多路分解的概念。

多路復(fù)用和多路分解分為兩種,即無(wú)連接的多路復(fù)用(多路分解)和面向連接的多路復(fù)用(多路分解)

無(wú)連接的多路復(fù)用和多路分解

開(kāi)發(fā)人員會(huì)編寫(xiě)代碼確定端口號(hào)是周知端口號(hào)還是時(shí)序分配的端口號(hào)。假如主機(jī) A 中的一個(gè) 10637 端口要向主機(jī) B 中的 45438 端口發(fā)送數(shù)據(jù),運(yùn)輸層采用的是?UDP?協(xié)議,數(shù)據(jù)在應(yīng)用層產(chǎn)生后,會(huì)在運(yùn)輸層中加工處理,然后在網(wǎng)絡(luò)層將數(shù)據(jù)封裝得到 IP 數(shù)據(jù)報(bào),IP 數(shù)據(jù)包通過(guò)鏈路層盡力而為的交付給主機(jī) B,然后主機(jī) B 會(huì)檢查報(bào)文段中的端口號(hào)判斷是哪個(gè)套接字的,這一系列的過(guò)程如下所示

40張圖帶你搞懂TCP和UDP

UDP 套接字就是一個(gè)二元組,二元組包含目的 IP 地址和目的端口號(hào)。

所以,如果兩個(gè) UDP 報(bào)文段有不同的源 IP 地址和/或相同的源端口號(hào),但是具有相同的目的 IP 地址和目的端口號(hào),那么這兩個(gè)報(bào)文會(huì)通過(guò)套接字定位到相同的目的進(jìn)程。

這里思考一個(gè)問(wèn)題,主機(jī) A 給主機(jī) B 發(fā)送一個(gè)消息,為什么還需要知道源端口號(hào)呢?比如我給妹子表達(dá)出我對(duì)你有點(diǎn)意思的信息,妹子還需要知道這個(gè)信息是從我的哪個(gè)器官發(fā)出的嗎?知道是我這個(gè)人對(duì)你有點(diǎn)意思不就完了?實(shí)際上是需要的,因?yàn)槊米尤绻磉_(dá)出她對(duì)你也有點(diǎn)意思,她是不是可能會(huì)親你一口,那她得知道往哪親吧?

這就是,在 A 到 B 的報(bào)文段中,源端口號(hào)會(huì)作為?返回地址?的一部分,即當(dāng) B 需要回發(fā)一個(gè)報(bào)文段給 A 時(shí),B 需要從 A 到 B 中的源端口號(hào)取值,如下圖所示

40張圖帶你搞懂TCP和UDP

面向連接的多路復(fù)用與多路分解

如果說(shuō)無(wú)連接的多路復(fù)用和多路分解指的是 UDP 的話(huà),那么面向連接的多路復(fù)用與多路分解指的是 TCP 了,TCP 和 UDP 在報(bào)文結(jié)構(gòu)上的差別是,UDP 是一個(gè)二元組而 TCP 是一個(gè)四元組,即源 IP 地址、目標(biāo) IP 地址、源端口號(hào)、目標(biāo)端口號(hào)?,這個(gè)我們上面也提到了。當(dāng)一個(gè) TCP 報(bào)文段從網(wǎng)絡(luò)到達(dá)一臺(tái)主機(jī)時(shí),這個(gè)主機(jī)會(huì)根據(jù)這四個(gè)值拆解到對(duì)應(yīng)的套接字上。

40張圖帶你搞懂TCP和UDP

上圖顯示了面向連接的多路復(fù)用和多路分解的過(guò)程,圖中主機(jī) C 向主機(jī) B 發(fā)起了兩個(gè) HTTP 請(qǐng)求,主機(jī) A 向主機(jī) C 發(fā)起了一個(gè) HTTP 請(qǐng)求,主機(jī) A、B、C 都有自己唯一的 IP 地址,當(dāng)主機(jī) C 發(fā)出 HTTP 請(qǐng)求后,主機(jī) B 能夠分解這兩個(gè) HTTP 連接,因?yàn)橹鳈C(jī) C 發(fā)出請(qǐng)求的兩個(gè)源端口號(hào)不同,所以對(duì)于主機(jī) B 來(lái)說(shuō),這是兩條請(qǐng)求,主機(jī) B 能夠進(jìn)行分解。對(duì)于主機(jī) A 和主機(jī) C 來(lái)說(shuō),這兩個(gè)主機(jī)有不同的 IP 地址,所以對(duì)于主機(jī) B 來(lái)說(shuō),也能夠進(jìn)行分解。

UDP

終于,我們開(kāi)始了對(duì) UDP 協(xié)議的探討,淦起!

UDP 的全稱(chēng)是?用戶(hù)數(shù)據(jù)報(bào)協(xié)議(UDP,User Datagram Protocol),UDP 為應(yīng)用程序提供了一種無(wú)需建立連接就可以發(fā)送封裝的 IP 數(shù)據(jù)包的方法。如果應(yīng)用程序開(kāi)發(fā)人員選擇的是 UDP 而不是 TCP 的話(huà),那么該應(yīng)用程序相當(dāng)于就是和 IP 直接打交道的。

從應(yīng)用程序傳遞過(guò)來(lái)的數(shù)據(jù),會(huì)附加上多路復(fù)用/多路分解的源和目的端口號(hào)字段,以及其他字段,然后將形成的報(bào)文傳遞給網(wǎng)絡(luò)層,網(wǎng)絡(luò)層將運(yùn)輸層報(bào)文段封裝到 IP 數(shù)據(jù)報(bào)中,然后盡力而為的交付給目標(biāo)主機(jī)。最關(guān)鍵的一點(diǎn)就是,使用 UDP 協(xié)議在將數(shù)據(jù)報(bào)傳遞給目標(biāo)主機(jī)時(shí),發(fā)送方和接收方的運(yùn)輸層實(shí)體間是沒(méi)有握手的。正因?yàn)槿绱?,UDP 被稱(chēng)為是無(wú)連接的協(xié)議。

UDP 特點(diǎn)

UDP 協(xié)議一般作為流媒體應(yīng)用、語(yǔ)音交流、視頻會(huì)議所使用的傳輸層協(xié)議,我們大家都知道的 DNS 協(xié)議底層也使用了 UDP 協(xié)議,這些應(yīng)用或協(xié)議之所以選擇 UDP 主要是因?yàn)橐韵逻@幾點(diǎn)

  • 速度快,采用 UDP 協(xié)議時(shí),只要應(yīng)用進(jìn)程將數(shù)據(jù)傳給 UDP,UDP 就會(huì)將此數(shù)據(jù)打包進(jìn) UDP 報(bào)文段并立刻傳遞給網(wǎng)絡(luò)層,然后 TCP 有擁塞控制的功能,它會(huì)在發(fā)送前判斷互聯(lián)網(wǎng)的擁堵情況,如果互聯(lián)網(wǎng)極度阻塞,那么就會(huì)抑制 TCP 的發(fā)送方。使用 UDP 的目的就是希望實(shí)時(shí)性。

  • 無(wú)須建立連接,TCP 在數(shù)據(jù)傳輸之前需要經(jīng)過(guò)三次握手的操作,而 UDP 則無(wú)須任何準(zhǔn)備即可進(jìn)行數(shù)據(jù)傳輸。因此 UDP 沒(méi)有建立連接的時(shí)延。如果使用 TCP 和 UDP 來(lái)比喻開(kāi)發(fā)人員:TCP 就是那種凡事都要設(shè)計(jì)好,沒(méi)設(shè)計(jì)不會(huì)進(jìn)行開(kāi)發(fā)的工程師,需要把一切因素考慮在內(nèi)后再開(kāi)干!所以非常靠譜;而 UDP 就是那種上來(lái)直接干干干,接到項(xiàng)目需求馬上就開(kāi)干,也不管設(shè)計(jì),也不管技術(shù)選型,就是干,這種開(kāi)發(fā)人員非常不靠譜,但是適合快速迭代開(kāi)發(fā),因?yàn)榭梢择R上上手!

  • 無(wú)連接狀態(tài),TCP 需要在端系統(tǒng)中維護(hù)連接狀態(tài),連接狀態(tài)包括接收和發(fā)送緩存、擁塞控制參數(shù)以及序號(hào)和確認(rèn)號(hào)的參數(shù),在 UDP 中沒(méi)有這些參數(shù),也沒(méi)有發(fā)送緩存和接受緩存。因此,某些專(zhuān)門(mén)用于某種特定應(yīng)用的服務(wù)器當(dāng)應(yīng)用程序運(yùn)行在 UDP 上,一般能支持更多的活躍用戶(hù)

  • 分組首部開(kāi)銷(xiāo)小,每個(gè) TCP 報(bào)文段都有 20 字節(jié)的首部開(kāi)銷(xiāo),而 UDP 僅僅只有 8 字節(jié)的開(kāi)銷(xiāo)。

這里需要注意一點(diǎn),并不是所有使用 UDP 協(xié)議的應(yīng)用層都是不可靠的,應(yīng)用程序可以自己實(shí)現(xiàn)可靠的數(shù)據(jù)傳輸,通過(guò)增加確認(rèn)和重傳機(jī)制。所以使用 UDP 協(xié)議最大的特點(diǎn)就是速度快。

UDP 報(bào)文結(jié)構(gòu)

下面來(lái)一起看一下 UDP 的報(bào)文結(jié)構(gòu),每個(gè) UDP 報(bào)文分為 UDP 報(bào)頭和 UDP 數(shù)據(jù)區(qū)兩部分。報(bào)頭由 4 個(gè) 16 位長(zhǎng)(2 字節(jié))字段組成,分別說(shuō)明該報(bào)文的源端口、目的端口、報(bào)文長(zhǎng)度和校驗(yàn)值。

40張圖帶你搞懂TCP和UDP

  • 源端口號(hào)(Source Port)?:這個(gè)字段占據(jù) UDP 報(bào)文頭的前 16 位,通常包含發(fā)送數(shù)據(jù)報(bào)的應(yīng)用程序所使用的 UDP 端口。接收端的應(yīng)用程序利用這個(gè)字段的值作為發(fā)送響應(yīng)的目的地址。這個(gè)字段是可選項(xiàng),有時(shí)不會(huì)設(shè)置源端口號(hào)。沒(méi)有源端口號(hào)就默認(rèn)為 0 ,通常用于不需要返回消息的通信中。

  • 目標(biāo)端口號(hào)(Destination Port): 表示接收端端口,字段長(zhǎng)為 16 位

  • 長(zhǎng)度(Length): 該字段占據(jù) 16 位,表示 UDP 數(shù)據(jù)報(bào)長(zhǎng)度,包含 UDP 報(bào)文頭和 UDP 數(shù)據(jù)長(zhǎng)度。因?yàn)?UDP 報(bào)文頭長(zhǎng)度是 8 個(gè)字節(jié),所以這個(gè)值最小為 8,最大長(zhǎng)度為 65535 字節(jié)。

  • 校驗(yàn)和(Checksum):UDP 使用校驗(yàn)和來(lái)保證數(shù)據(jù)安全性,UDP 的校驗(yàn)和也提供了差錯(cuò)檢測(cè)功能,差錯(cuò)檢測(cè)用于校驗(yàn)報(bào)文段從源到目標(biāo)主機(jī)的過(guò)程中,數(shù)據(jù)的完整性是否發(fā)生了改變。發(fā)送方的 UDP 對(duì)報(bào)文段中的 16 比特字的和進(jìn)行反碼運(yùn)算,求和時(shí)遇到的位溢出都會(huì)被忽略,比如下面這個(gè)例子,三個(gè) 16 比特的數(shù)字進(jìn)行相加

40張圖帶你搞懂TCP和UDP

這些 16 比特的前兩個(gè)和是

40張圖帶你搞懂TCP和UDP

然后再將上面的結(jié)果和第三個(gè) 16 比特的數(shù)進(jìn)行相加

40張圖帶你搞懂TCP和UDP

最后一次相加的位會(huì)進(jìn)行溢出,溢出位 1 要被舍棄,然后進(jìn)行反碼運(yùn)算,反碼運(yùn)算就是將所有的 1 變?yōu)?0 ,0 變?yōu)?1。因此?1000 0100 1001 0101?的反碼就是?0111 1011 0110 1010,這就是校驗(yàn)和,如果在接收方,數(shù)據(jù)沒(méi)有出現(xiàn)差錯(cuò),那么全部的 4 個(gè) 16 比特的數(shù)值進(jìn)行運(yùn)算,同時(shí)也包括校驗(yàn)和,如果最后結(jié)果的值不是 1111 1111 1111 1111 的話(huà),那么就表示傳輸過(guò)程中的數(shù)據(jù)出現(xiàn)了差錯(cuò)。

下面來(lái)想一個(gè)問(wèn)題,為什么 UDP 會(huì)提供差錯(cuò)檢測(cè)的功能?

這其實(shí)是一種?端到端?的設(shè)計(jì)原則,這個(gè)原則說(shuō)的是要讓傳輸中各種錯(cuò)誤發(fā)生的概率降低到一個(gè)可以接受的水平

文件從主機(jī)A傳到主機(jī)B,也就是說(shuō)AB主機(jī)要通信,需要經(jīng)過(guò)三個(gè)環(huán)節(jié):首先是主機(jī)A從磁盤(pán)上讀取文件并將數(shù)據(jù)分組成一個(gè)個(gè)數(shù)據(jù)包packet,,然后數(shù)據(jù)包通過(guò)連接主機(jī)A和主機(jī)B的網(wǎng)絡(luò)傳輸?shù)街鳈C(jī)B,最后是主機(jī)B收到數(shù)據(jù)包并將數(shù)據(jù)包寫(xiě)入磁盤(pán)。在這個(gè)看似簡(jiǎn)單其實(shí)很復(fù)雜的過(guò)程中可能會(huì)由于某些原因而影響正常通信。比如:磁盤(pán)上文件讀寫(xiě)錯(cuò)誤、緩沖溢出、內(nèi)存出錯(cuò)、網(wǎng)絡(luò)擁擠等等這些因素都有可能導(dǎo)致數(shù)據(jù)包的出錯(cuò)或者丟失,由此可見(jiàn)用于通信的網(wǎng)絡(luò)是不可靠的。

由于實(shí)現(xiàn)通信只要經(jīng)過(guò)上述三個(gè)環(huán)節(jié),那么我們就想是否在其中某個(gè)環(huán)節(jié)上增加一個(gè)檢錯(cuò)糾錯(cuò)機(jī)制來(lái)用于對(duì)信息進(jìn)行把關(guān)呢?

網(wǎng)絡(luò)層肯定不能做這件事,因?yàn)榫W(wǎng)絡(luò)層的最主要目的是增大數(shù)據(jù)傳輸?shù)乃俾?,網(wǎng)絡(luò)層不需要考慮數(shù)據(jù)的完整性,數(shù)據(jù)的完整性和正確性交給端系統(tǒng)去檢測(cè)就行了,因此在數(shù)據(jù)傳輸中,對(duì)于網(wǎng)絡(luò)層只能要求其提供盡可能好的數(shù)據(jù)傳輸服務(wù),而不可能寄希望于網(wǎng)絡(luò)層提供數(shù)據(jù)完整性的服務(wù)。

UDP 不可靠的原因是它雖然提供差錯(cuò)檢測(cè)的功能,但是對(duì)于差錯(cuò)沒(méi)有恢復(fù)能力更不會(huì)有重傳機(jī)制。

TCP

UDP 是一種沒(méi)有復(fù)雜的控制,提供無(wú)連接通信服務(wù)的一種協(xié)議,換句話(huà)說(shuō),它將部分控制部分交給應(yīng)用程序去處理,自己只提供作為傳輸層協(xié)議最基本的功能。

而與 UDP 不同的是,同樣作為傳輸層協(xié)議,TCP 協(xié)議要比 UDP 的功能多很多。

TCP?的全稱(chēng)是?Transmission Control Protocol,它被稱(chēng)為是一種面向連接(connection-oriented)?的協(xié)議,這是因?yàn)橐粋€(gè)應(yīng)用程序開(kāi)始向另一個(gè)應(yīng)用程序發(fā)送數(shù)據(jù)之前,這兩個(gè)進(jìn)程必須先進(jìn)行握手,握手是一個(gè)邏輯連接,并不是兩個(gè)主機(jī)之間進(jìn)行真實(shí)的握手。

40張圖帶你搞懂TCP和UDP

這個(gè)連接是指各種設(shè)備、線(xiàn)路或者網(wǎng)絡(luò)中進(jìn)行通信的兩個(gè)應(yīng)用程序?yàn)榱讼嗷鬟f消息而專(zhuān)有的、虛擬的通信鏈路,也叫做虛擬電路。

一旦主機(jī) A 和主機(jī) B 建立了連接,那么進(jìn)行通信的應(yīng)用程序只使用這個(gè)虛擬的通信線(xiàn)路發(fā)送和接收數(shù)據(jù)就可以保證數(shù)據(jù)的傳輸,TCP 協(xié)議負(fù)責(zé)控制連接的建立、斷開(kāi)、保持等工作。

TCP 連接是全雙工服務(wù)(full-duplex service)?的,全雙工是什么意思?全雙工指的是主機(jī) A 與另外一個(gè)主機(jī) B 存在一條 TCP 連接,那么應(yīng)用程數(shù)據(jù)就可以從主機(jī) B 流向主機(jī) A 的同時(shí),也從主機(jī) A 流向主機(jī) B。

TCP 只能進(jìn)行?點(diǎn)對(duì)點(diǎn)(point-to-point)?連接,那么所謂的多播,即一個(gè)主機(jī)對(duì)多個(gè)接收方發(fā)送消息的情況是不存在的,TCP 連接只能連接兩個(gè)一對(duì)主機(jī)。

40張圖帶你搞懂TCP和UDP

TCP 的連接建立需要經(jīng)過(guò)三次握手,這個(gè)我們下面再說(shuō)。一旦 TCP 連接建立后,主機(jī)之間就可以相互發(fā)送數(shù)據(jù)了,客戶(hù)進(jìn)程通過(guò)套接字傳送數(shù)據(jù)流。數(shù)據(jù)一旦通過(guò)套接字后,它就由客戶(hù)中運(yùn)行的 TCP 協(xié)議所控制。

TCP 會(huì)將數(shù)據(jù)臨時(shí)存儲(chǔ)到連接的發(fā)送緩存(send buffer)?中,這個(gè) send buffer 是三次握手之間設(shè)置的緩存之一,然后 TCP 在合適的時(shí)間將發(fā)送緩存中的數(shù)據(jù)發(fā)送到目標(biāo)主機(jī)的接收緩存中,實(shí)際上,每一端都會(huì)有發(fā)送緩存和接收緩存,如下所示

40張圖帶你搞懂TCP和UDP

主機(jī)之間的發(fā)送是以?報(bào)文段(segment)?進(jìn)行的,那么什么是 Segement 呢?

TCP 會(huì)將要傳輸?shù)臄?shù)據(jù)流分為多個(gè)塊(chunk),然后向每個(gè) chunk 中添加 TCP 標(biāo)頭,這樣就形成了一個(gè) TCP 段也就是報(bào)文段。每一個(gè)報(bào)文段可以傳輸?shù)拈L(zhǎng)度是有限的,不能超過(guò)最大數(shù)據(jù)長(zhǎng)度(Maximum Segment Size),俗稱(chēng)?MSS。在報(bào)文段向下傳輸?shù)倪^(guò)程中,會(huì)經(jīng)過(guò)鏈路層,鏈路層有一個(gè)?Maximum Transmission Unit?,最大傳輸單元 MTU, 即數(shù)據(jù)鏈路層上所能通過(guò)最大數(shù)據(jù)包的大小,最大傳輸單元通常與通信接口有關(guān)。

那么 MSS 和 MTU 有啥關(guān)系呢?

因?yàn)橛?jì)算機(jī)網(wǎng)絡(luò)是分層考慮的,這個(gè)很重要,不同層的稱(chēng)呼不一樣,對(duì)于傳輸層來(lái)說(shuō),稱(chēng)為報(bào)文段而對(duì)網(wǎng)絡(luò)層來(lái)說(shuō)就叫做 IP 數(shù)據(jù)包,所以,MTU 可以認(rèn)為是網(wǎng)絡(luò)層能夠傳輸?shù)淖畲?IP 數(shù)據(jù)包,而 MSS(Maximum segment size)可以認(rèn)為是傳輸層的概念,也就是 TCP 數(shù)據(jù)包每次能夠傳輸?shù)淖畲罅?/strong>。

TCP 報(bào)文段結(jié)構(gòu)

在簡(jiǎn)單聊了聊 TCP 連接后,下面我們就來(lái)聊一下 TCP 的報(bào)文段結(jié)構(gòu),如下圖所示

40張圖帶你搞懂TCP和UDP

TCP 報(bào)文段結(jié)構(gòu)相比 UDP 報(bào)文結(jié)構(gòu)多了很多內(nèi)容。但是前兩個(gè) 32 比特的字段是一樣的。它們是?源端口號(hào)?和?目標(biāo)端口號(hào),我們知道,這兩個(gè)字段是用于多路復(fù)用和多路分解的。另外,和 UDP 一樣,TCP 也包含校驗(yàn)和(checksum field)?,除此之外,TCP 報(bào)文段首部還有下面這些

  • 32 比特的序號(hào)字段(sequence number field)?和 32 比特的確認(rèn)號(hào)字段(acknowledgment number field)?。這些字段被 TCP 發(fā)送方和接收方用來(lái)實(shí)現(xiàn)可靠的數(shù)據(jù)傳輸。

  • 4 比特的首部字段長(zhǎng)度字段(header length field),這個(gè)字段指示了以 32 比特的字為單位的 TCP 首部長(zhǎng)度。TCP 首部的長(zhǎng)度是可變的,但是通常情況下,選項(xiàng)字段為空,所以 TCP 首部字段的長(zhǎng)度是 20 字節(jié)。

  • 16 比特的?接受窗口字段(receive window field)?,這個(gè)字段用于流量控制。它用于指示接收方能夠/愿意接受的字節(jié)數(shù)量

  • 可變的選項(xiàng)字段(options field),這個(gè)字段用于發(fā)送方和接收方協(xié)商最大報(bào)文長(zhǎng)度,也就是 MSS 時(shí)使用

  • 6 比特的?標(biāo)志字段(flag field),?ACK?標(biāo)志用于指示確認(rèn)字段中的值是有效的,這個(gè)報(bào)文段包括一個(gè)對(duì)已被成功接收?qǐng)?bào)文段的確認(rèn);RST、SYNFIN?標(biāo)志用于連接的建立和關(guān)閉;CWR?和?ECE?用于擁塞控制;PSH?標(biāo)志用于表示立刻將數(shù)據(jù)交給上層處理;URG?標(biāo)志用來(lái)表示數(shù)據(jù)中存在需要被上層處理的?緊急?數(shù)據(jù)。緊急數(shù)據(jù)最后一個(gè)字節(jié)由 16 比特的緊急數(shù)據(jù)指針字段(urgeent data pointer field)?指出。一般情況下,PSH 和 URG 并沒(méi)有使用。

TCP 的各種功能和特點(diǎn)都是通過(guò) TCP 報(bào)文結(jié)構(gòu)來(lái)體現(xiàn)的,在聊完 TCP 報(bào)文結(jié)構(gòu)之后,我們下面就來(lái)聊一下 TCP 有哪些功能及其特點(diǎn)了。

序號(hào)、確認(rèn)號(hào)實(shí)現(xiàn)傳輸可靠性

TCP 報(bào)文段首部中兩個(gè)最重要的字段就是?序號(hào)?和?確認(rèn)號(hào),這兩個(gè)字段是 TCP 實(shí)現(xiàn)可靠性的基礎(chǔ),那么你肯定好奇如何實(shí)現(xiàn)可靠性呢?要了解這一點(diǎn),首先我們得先知道這兩個(gè)字段里面存了哪些內(nèi)容吧?

一個(gè)報(bào)文段的序號(hào)就是數(shù)據(jù)流的字節(jié)編號(hào)?。因?yàn)?TCP 會(huì)把數(shù)據(jù)流分割成為一段一段的字節(jié)流,因?yàn)樽止?jié)流本身是有序的,所以每一段的字節(jié)編號(hào)就是標(biāo)示是哪一段的字節(jié)流。比如,主機(jī) A 要給主機(jī) B 發(fā)送一條數(shù)據(jù)。數(shù)據(jù)經(jīng)過(guò)應(yīng)用層產(chǎn)生后會(huì)有一串?dāng)?shù)據(jù)流,數(shù)據(jù)流會(huì)經(jīng)過(guò) TCP 分割,分割的依據(jù)就是 MSS,假設(shè)數(shù)據(jù)是 10000 字節(jié),MSS 是 2000 字節(jié),那么 TCP 就會(huì)把數(shù)據(jù)拆分成 0 - 1999 , 2000 - 3999 的段,依次類(lèi)推。

所以,第一個(gè)數(shù)據(jù) 0 - 1999 的首字節(jié)編號(hào)就是 0 ,2000 - 3999 的首字節(jié)編號(hào)就是 2000 。

然后,每個(gè)序號(hào)都會(huì)被填入 TCP 報(bào)文段首部的序號(hào)字段中。

40張圖帶你搞懂TCP和UDP

至于確認(rèn)號(hào)的話(huà),會(huì)比序號(hào)要稍微麻煩一些。這里我們先拓展下幾種通信模型。

  • 單工通信:?jiǎn)喂?shù)據(jù)傳輸只支持?jǐn)?shù)據(jù)在一個(gè)方向上傳輸;在同一時(shí)間只有一方能接受或發(fā)送信息,不能實(shí)現(xiàn)雙向通信,比如廣播、電視等。

  • 雙工通信是一種點(diǎn)對(duì)點(diǎn)系統(tǒng),由兩個(gè)或者多個(gè)在兩個(gè)方向上相互通信的連接方或者設(shè)備組成。雙工通信模型有兩種:全雙工(FDX)和半雙工(HDX)

  • 全雙工:在全雙工系統(tǒng)中,連接雙方可以相互通信,一個(gè)最常見(jiàn)的例子就是電話(huà)通信。全雙工通信是兩個(gè)單工通信方式的結(jié)合,它要求發(fā)送設(shè)備和接收設(shè)備都有獨(dú)立的接收和發(fā)送能力。

  • 半雙工:在半雙工系統(tǒng)中,連接雙方可以彼此通信,但不能同時(shí)通信,比如對(duì)講機(jī),只有把按鈕按住的人才能夠講話(huà),只有一個(gè)人講完話(huà)后另外一個(gè)人才能講話(huà)。

單工、半雙工、全雙工通信如下圖所示

40張圖帶你搞懂TCP和UDP

TCP 是一種全雙工的通信協(xié)議,因此主機(jī) A 在向主機(jī) B 發(fā)送消息的過(guò)程中,也在接受來(lái)自主機(jī) B 的數(shù)據(jù)。主機(jī) A 填充進(jìn)報(bào)文段的確認(rèn)號(hào)是期望從主機(jī) B 收到的下一字節(jié)的序號(hào)。稍微有點(diǎn)繞,我們來(lái)舉個(gè)例子看一下。比如主機(jī) A 收到了來(lái)自主機(jī) B 發(fā)送的編號(hào)為 0 - 999 字節(jié)的報(bào)文段,這個(gè)報(bào)文段會(huì)寫(xiě)入序號(hào)中,隨后主機(jī) A 期望能夠從主機(jī) B 收到 1000 - 剩下的報(bào)文段,因此,主機(jī) A 發(fā)送到主機(jī) B 的報(bào)文段中,它的確認(rèn)號(hào)就是 1000 。

累積確認(rèn)

這里再舉出一個(gè)例子,比如主機(jī) A 在發(fā)送 0 - 999 報(bào)文段后,期望能夠接受到 1000 之后的報(bào)文段,但是主機(jī) B 卻給主機(jī) A 發(fā)送了一個(gè) 1500 之后的報(bào)文段,那么主機(jī) A 是否還會(huì)繼續(xù)進(jìn)行等待呢?

答案顯然是會(huì)的,因?yàn)?TCP 只會(huì)確認(rèn)流中至第一個(gè)丟失字節(jié)為止的字節(jié),因?yàn)?1500 雖然屬于 1000 之后的字節(jié),但是主機(jī) B 沒(méi)有給主機(jī) A 發(fā)送 1000 - 1499 之間的字節(jié),所以主機(jī) A 會(huì)繼續(xù)等待。

在了解完序號(hào)和確認(rèn)號(hào)之后,我們下面來(lái)聊一下 TCP 的發(fā)送過(guò)程。下面是一個(gè)正常的發(fā)送過(guò)程

40張圖帶你搞懂TCP和UDP

TCP 通過(guò)肯定的確認(rèn)應(yīng)答(ACK)?來(lái)實(shí)現(xiàn)可靠的數(shù)據(jù)傳輸,當(dāng)主機(jī) A將數(shù)據(jù)發(fā)出之后會(huì)等待主機(jī) B 的響應(yīng)。如果有確認(rèn)應(yīng)答(ACK),說(shuō)明數(shù)據(jù)已經(jīng)成功到達(dá)對(duì)端。反之,則數(shù)據(jù)很可能會(huì)丟失。

如下圖所示,如果在一定時(shí)間內(nèi)主機(jī) A 沒(méi)有等到確認(rèn)應(yīng)答,則認(rèn)為主機(jī) B 發(fā)送的報(bào)文段已經(jīng)丟失,并進(jìn)行重發(fā)。

40張圖帶你搞懂TCP和UDP

主機(jī) A 給主機(jī) B 的響應(yīng)可能由于網(wǎng)絡(luò)抖動(dòng)等原因無(wú)法到達(dá),那么在經(jīng)過(guò)特定的時(shí)間間隔后,主機(jī) A 將重新發(fā)送報(bào)文段。

主機(jī) A 沒(méi)有收到主機(jī) B 的響應(yīng)還可能是因?yàn)橹鳈C(jī) B 在發(fā)送給主機(jī) A 的過(guò)程中丟失。

40張圖帶你搞懂TCP和UDP

如上圖所示,由主機(jī) B 返回的確認(rèn)應(yīng)答,由于網(wǎng)絡(luò)擁堵等原因在傳送的過(guò)程中丟失,并沒(méi)有到達(dá)主機(jī) A。主機(jī) A 會(huì)等待一段時(shí)間,如果在這段時(shí)間內(nèi)主機(jī) A 仍沒(méi)有等到主機(jī) B 的響應(yīng),那么主機(jī) A 會(huì)重新發(fā)送報(bào)文段。

那么現(xiàn)在就存在一個(gè)問(wèn)題,如果主機(jī) A 給主機(jī) B 發(fā)送了一個(gè)報(bào)文段后,主機(jī) B 接受到報(bào)文段發(fā)送響應(yīng),此刻由于網(wǎng)絡(luò)原因,這個(gè)報(bào)文段并未到達(dá),等到一段時(shí)間后主機(jī) A 重新發(fā)送報(bào)文段,然后此時(shí)主機(jī) B 發(fā)送的響應(yīng)在主機(jī) A 第二次發(fā)送后失序到達(dá)主機(jī) A,那么主機(jī) A 應(yīng)該如何處理呢?

40張圖帶你搞懂TCP和UDP

TCP RFC 并未為此做任何規(guī)定,也就是說(shuō),我們可以自己決定如何處理失序到達(dá)的報(bào)文段。一般處理方式有兩種

  • 接收方立刻丟棄失序的報(bào)文段

  • 接收方接受失序到達(dá)的報(bào)文段,并等待后續(xù)的報(bào)文段

一般來(lái)說(shuō)通常采取的做法是第二種。

傳輸控制

利用窗口控制提高速度

前面我們介紹了 TCP 是以數(shù)據(jù)段的形式進(jìn)行發(fā)送,如果經(jīng)過(guò)一段時(shí)間內(nèi)主機(jī) A 等不到主機(jī) B 的響應(yīng),主機(jī) A 就會(huì)重新發(fā)送報(bào)文段,接受到主機(jī) B 的響應(yīng),再會(huì)繼續(xù)發(fā)送后面的報(bào)文段,我們現(xiàn)在看到,這一問(wèn)一答的形式還存在許多條件,比如響應(yīng)未收到、等待響應(yīng)等,那么對(duì)崇尚性能的互聯(lián)網(wǎng)來(lái)說(shuō),這種形式的性能應(yīng)該不會(huì)很高。

40張圖帶你搞懂TCP和UDP

那么如何提升性能呢?

為了解決這個(gè)問(wèn)題,TCP 引入了?窗口?這個(gè)概念,即使在往返時(shí)間較長(zhǎng)、頻次很多的情況下,它也能控制網(wǎng)絡(luò)性能的下降,聽(tīng)起來(lái)很牛批,那它是如何實(shí)現(xiàn)的呢?

如下圖所示

40張圖帶你搞懂TCP和UDP

我們之前每次請(qǐng)求發(fā)送都是以報(bào)文段的形式進(jìn)行的,引入窗口后,每次請(qǐng)求都可以發(fā)送多個(gè)報(bào)文段,也就是說(shuō)一個(gè)窗口可以發(fā)送多個(gè)報(bào)文段。窗口大小就是指無(wú)需等待確認(rèn)應(yīng)答就可以繼續(xù)發(fā)送報(bào)文段的最大值。

在這個(gè)窗口機(jī)制中,大量使用了?緩沖區(qū)?,通過(guò)對(duì)多個(gè)段同時(shí)進(jìn)行確認(rèn)應(yīng)答的功能。

如下圖所示,發(fā)送報(bào)文段中高亮部分即是我們提到的窗口,在窗口內(nèi),即使沒(méi)有收到確認(rèn)應(yīng)答也可以把請(qǐng)求發(fā)送出去。不過(guò),在整個(gè)窗口的確認(rèn)應(yīng)答沒(méi)有到達(dá)之前,如果部分報(bào)文段丟失,那么主機(jī) A 將仍會(huì)重傳。為此,主機(jī) A 需要設(shè)置緩存來(lái)保留這些需要重傳的報(bào)文段,直到收到他們的確認(rèn)應(yīng)答。

40張圖帶你搞懂TCP和UDP

在滑動(dòng)窗口以外的部分是尚未發(fā)送的報(bào)文段和已經(jīng)接受到的報(bào)文段,如果報(bào)文段已經(jīng)收到確認(rèn)則不可進(jìn)行重發(fā),此時(shí)報(bào)文段就可以從緩沖區(qū)中清除。

在收到確認(rèn)的情況下,會(huì)將窗口滑動(dòng)到確認(rèn)應(yīng)答中確認(rèn)號(hào)的位置,如上圖所示,這樣可以順序的將多個(gè)段同時(shí)發(fā)送,用以提高通信性能,這種窗口也叫做?滑動(dòng)窗口(Sliding window)。

窗口控制和重發(fā)

報(bào)文段的發(fā)送和接收,必然伴隨著報(bào)文段的丟失和重發(fā),窗口也是同樣如此,如果在窗口中報(bào)文段發(fā)送過(guò)程中出現(xiàn)丟失怎么辦?

首先我們先考慮確認(rèn)應(yīng)答沒(méi)有返回的情況。在這種情況下,主機(jī) A 發(fā)送的報(bào)文段到達(dá)主機(jī) B,是不需要再進(jìn)行重發(fā)的。這和單個(gè)報(bào)文段的發(fā)送不一樣,如果發(fā)送單個(gè)報(bào)文段,即使確認(rèn)應(yīng)答沒(méi)有返回,也要進(jìn)行重發(fā)。

40張圖帶你搞懂TCP和UDP

窗口在一定程度上比較大時(shí),即使有少部分確認(rèn)應(yīng)答的丟失,也不會(huì)重新發(fā)送報(bào)文段。

我們知道,如果在某個(gè)情況下由于發(fā)送的報(bào)文段丟失,導(dǎo)致接受主機(jī)未收到請(qǐng)求,或者主機(jī)返回的響應(yīng)未到達(dá)客戶(hù)端的話(huà),會(huì)經(jīng)過(guò)一段時(shí)間重傳報(bào)文。那么在使用窗口的情況下,報(bào)文段丟失會(huì)怎么樣呢?

如下圖所示,報(bào)文段 0 - 999 丟失后,但是主機(jī) A 并不會(huì)等待,主機(jī) A 會(huì)繼續(xù)發(fā)送余下的報(bào)文段,主機(jī) B 發(fā)送的確認(rèn)應(yīng)答卻一直是 1000,同一個(gè)確認(rèn)號(hào)的應(yīng)答報(bào)文會(huì)被持續(xù)不斷的返回,如果發(fā)送端主機(jī)在連續(xù) 3 次收到同一個(gè)確認(rèn)應(yīng)答后,就會(huì)將其所對(duì)應(yīng)的數(shù)據(jù)重發(fā),這種機(jī)制要比之前提到的超時(shí)重發(fā)更加高效,這種機(jī)制也被稱(chēng)為?高速重發(fā)控制。這種重發(fā)的確認(rèn)應(yīng)答也被稱(chēng)為?冗余 ACK(響應(yīng))

40張圖帶你搞懂TCP和UDP

主機(jī) B 在沒(méi)有接收到自己期望序列號(hào)的報(bào)文段時(shí),會(huì)對(duì)之前收到的數(shù)據(jù)進(jìn)行確認(rèn)應(yīng)答。發(fā)送端則一旦收到某個(gè)確認(rèn)應(yīng)答后,又連續(xù)三次收到同樣的確認(rèn)應(yīng)答,那么就會(huì)認(rèn)為報(bào)文段已經(jīng)丟失。需要進(jìn)行重發(fā)。使用這種機(jī)制可以提供更為快速的重發(fā)服務(wù)

流量控制

前面聊的是傳輸控制,下面 cxuan 再和你聊一下?流量控制。我們知道,在每個(gè) TCP 連接的一側(cè)主機(jī)都會(huì)有一個(gè) socket 緩沖區(qū),緩沖區(qū)會(huì)為每個(gè)連接設(shè)置接收緩存和發(fā)送緩存,當(dāng) TCP 建立連接后,從應(yīng)用程序產(chǎn)生的數(shù)據(jù)就會(huì)到達(dá)接收方的接收緩沖區(qū)中,接收方的應(yīng)用程序并不一定會(huì)馬上讀取緩沖區(qū)的數(shù)據(jù),它需要等待操作系統(tǒng)分配時(shí)間片。如果此時(shí)發(fā)送方的應(yīng)用程序產(chǎn)生數(shù)據(jù)過(guò)快,而接收方讀取接受緩沖區(qū)的數(shù)據(jù)相對(duì)較慢的話(huà),那么接收方中緩沖區(qū)的數(shù)據(jù)將會(huì)溢出。

但是還好,TCP 有?流量控制服務(wù)(flow-control service)?用于消除緩沖區(qū)溢出的情況。流量控制是一個(gè)速度匹配服務(wù),即發(fā)送方的發(fā)送速率與接受方應(yīng)用程序的讀取速率相匹配。

TCP 通過(guò)使用一個(gè)?接收窗口(receive window)?的變量來(lái)提供流量控制。接受窗口會(huì)給發(fā)送方一個(gè)指示到底還有多少可用的緩存空間。發(fā)送端會(huì)根據(jù)接收端的實(shí)際接受能力來(lái)控制發(fā)送的數(shù)據(jù)量。

接收端主機(jī)向發(fā)送端主機(jī)通知自己可以接收數(shù)據(jù)的大小,發(fā)送端會(huì)發(fā)送不超過(guò)這個(gè)限度的數(shù)據(jù),這個(gè)大小限度就是窗口大小,還記得 TCP 的首部么,有一個(gè)接收窗口,我們上面聊的時(shí)候說(shuō)這個(gè)字段用于流量控制。它用于指示接收方能夠/愿意接受的字節(jié)數(shù)量。

那么只知道這個(gè)字段用于流量控制,那么如何控制呢?

發(fā)送端主機(jī)會(huì)定期發(fā)送一個(gè)窗口探測(cè)包,這個(gè)包用于探測(cè)接收端主機(jī)是否還能夠接受數(shù)據(jù),當(dāng)接收端的緩沖區(qū)一旦面臨數(shù)據(jù)溢出的風(fēng)險(xiǎn)時(shí),窗口大小的值也隨之被設(shè)置為一個(gè)更小的值通知發(fā)送端,從而控制數(shù)據(jù)發(fā)送量。

下面是一個(gè)流量控制示意圖

40張圖帶你搞懂TCP和UDP

發(fā)送端主機(jī)根據(jù)接收端主機(jī)的窗口大小進(jìn)行流量控制。由此也可以防止發(fā)送端主機(jī)一次發(fā)送過(guò)大數(shù)據(jù)導(dǎo)致接收端主機(jī)無(wú)法處理。

如上圖所示,當(dāng)主機(jī) B 收到報(bào)文段 2000 - 2999 之后緩沖區(qū)已滿(mǎn),不得不暫時(shí)停止接收數(shù)據(jù)。然后主機(jī) A 發(fā)送窗口探測(cè)包,窗口探測(cè)包非常小僅僅一個(gè)字節(jié)。然后主機(jī) B 更新緩沖區(qū)接收窗口大小并發(fā)送窗口更新通知給主機(jī) A,然后主機(jī) A 再繼續(xù)發(fā)送報(bào)文段。

在上面的發(fā)送過(guò)程中,窗口更新通知可能會(huì)丟失,一旦丟失發(fā)送端就不會(huì)發(fā)送數(shù)據(jù),所以窗口探測(cè)包會(huì)隨機(jī)發(fā)送,以避免這種情況發(fā)生。

連接管理

在繼續(xù)介紹下面有意思的特性之前,我們先來(lái)把關(guān)注點(diǎn)放在 TCP 的連接管理上,因?yàn)闆](méi)有 TCP 連接,也就沒(méi)有后續(xù)的一系列 TCP 特性什么事兒了。假設(shè)運(yùn)行在一臺(tái)主機(jī)上的進(jìn)程想要和另一臺(tái)主機(jī)上的進(jìn)程建立一條 TCP 連接,那么客戶(hù)中的 TCP 會(huì)使用下面這些步驟與服務(wù)器中的 TCP 建立連接。

  • 首先,客戶(hù)端首先向服務(wù)器發(fā)送一個(gè)特殊的 TCP 報(bào)文段。這個(gè)報(bào)文段首部不包含應(yīng)用層數(shù)據(jù),但是在報(bào)文段的首部中有一個(gè)?SYN 標(biāo)志位?被置為 1。因此,這個(gè)特殊的報(bào)文段也可以叫做 SYN 報(bào)文段。然后,客戶(hù)端隨機(jī)選擇一個(gè)初始序列號(hào)(client_isn)?,并將此數(shù)字放入初始 TCP SYN 段的序列號(hào)字段中,SYN 段又被封裝在 IP 數(shù)據(jù)段中發(fā)送給服務(wù)器。

  • 一旦包含 IP 數(shù)據(jù)段到達(dá)服務(wù)器后,服務(wù)端會(huì)從 IP 數(shù)據(jù)段中提取 TCP SYN 段,將 TCP 緩沖區(qū)和變量分配給連接,然后給客戶(hù)端發(fā)送一個(gè)連接所允許的報(bào)文段。這個(gè)連接所允許的報(bào)文段也不包括任何應(yīng)用層數(shù)據(jù)。然而,它卻包含了三個(gè)非常重要的信息。

這些緩沖區(qū)和變量的分配使 TCP 容易受到稱(chēng)為 SYN 泛洪的拒絕服務(wù)攻擊。

  • 首先,SYN 比特被置為 1 。

  • 然后,TCP 報(bào)文段的首部確認(rèn)號(hào)被設(shè)置為?client_isn + 1

  • 最后,服務(wù)器選擇自己的初始序號(hào)(server_isn),并將其放置到 TCP 報(bào)文段首部的序號(hào)字段中。

    如果用大白話(huà)解釋下就是,我收到了你發(fā)起建立連接的 SYN 報(bào)文段,這個(gè)報(bào)文段具有首部字段 client_isn。我同意建立該連接,我自己的初始序號(hào)是 server_isn。這個(gè)允許連接的報(bào)文段被稱(chēng)為?SYNACK 報(bào)文段

  • 第三步,在收到 SYNACK 報(bào)文段后,客戶(hù)端也要為該連接分配緩沖區(qū)和變量。客戶(hù)端主機(jī)向服務(wù)器發(fā)送另外一個(gè)報(bào)文段,最后一個(gè)報(bào)文段對(duì)服務(wù)器發(fā)送的響應(yīng)報(bào)文做了確認(rèn),確認(rèn)的標(biāo)準(zhǔn)是客戶(hù)端發(fā)送的數(shù)據(jù)段中確認(rèn)號(hào)為 server_isn + 1,因?yàn)檫B接已經(jīng)建立,所以 SYN 比特被置為 0 。以上就是 TCP 建立連接的三次數(shù)據(jù)段發(fā)送過(guò)程,也被稱(chēng)為?三次握手。

一旦完成這三個(gè)步驟,客戶(hù)和服務(wù)器主機(jī)就可以相互發(fā)送報(bào)文段了,在以后的每一個(gè)報(bào)文段中,SYN 比特都被置為 0 ,整個(gè)過(guò)程描述如下圖所示

40張圖帶你搞懂TCP和UDP

在客戶(hù)端主機(jī)和服務(wù)端主機(jī)建立連接后,參與一條 TCP 連接的兩個(gè)進(jìn)程中的任何一個(gè)都能終止 TCP 連接。連接結(jié)束后,主機(jī)中的緩存和變量將會(huì)被釋放。假設(shè)客戶(hù)端主機(jī)想要終止 TCP 連接,它會(huì)經(jīng)歷如下過(guò)程

客戶(hù)應(yīng)用進(jìn)程發(fā)出一個(gè)關(guān)閉命令,客戶(hù) TCP 向服務(wù)器進(jìn)程發(fā)送一個(gè)特殊的 TCP 報(bào)文段,這個(gè)特殊的報(bào)文段的首部標(biāo)志 FIN 被設(shè)置為 1 。當(dāng)服務(wù)器收到這個(gè)報(bào)文段后,就會(huì)向發(fā)送方發(fā)送一個(gè)確認(rèn)報(bào)文段。然后,服務(wù)器發(fā)送它自己的終止報(bào)文段,F(xiàn)IN 位被設(shè)置為 1 ??蛻?hù)端對(duì)這個(gè)終止報(bào)文段進(jìn)行確認(rèn)。此時(shí),在兩臺(tái)主機(jī)上用于該連接的所有資源都被釋放了,如下圖所示

40張圖帶你搞懂TCP和UDP

在一個(gè) TCP 連接的生命周期內(nèi),運(yùn)行在每臺(tái)主機(jī)中的 TCP 協(xié)議都會(huì)在各種?TCP 狀態(tài)(TCP State)?之間進(jìn)行變化,TCP 的狀態(tài)主要有?LISTEN、SYN-SEND、SYN-RECEIVED、ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT 和 CLOSED?。這些狀態(tài)的解釋如下

  • LISTEN: 表示等待任何來(lái)自遠(yuǎn)程 TCP 和端口的連接請(qǐng)求。

  • SYN-SEND: 表示發(fā)送連接請(qǐng)求后等待匹配的連接請(qǐng)求。

  • SYN-RECEIVED: 表示已接收并發(fā)送連接請(qǐng)求后等待連接確認(rèn),也就是 TCP 三次握手中第二步后服務(wù)端的狀態(tài)

  • ESTABLISHED: 表示已經(jīng)連接已經(jīng)建立,可以將應(yīng)用數(shù)據(jù)發(fā)送給其他主機(jī)

上面這四種狀態(tài)是 TCP 三次握手所涉及的。

  • FIN-WAIT-1: 表示等待來(lái)自遠(yuǎn)程 TCP 的連接終止請(qǐng)求,或者等待先前發(fā)送的連接終止請(qǐng)求的確認(rèn)。

  • FIN-WAIT-2: 表示等待來(lái)自遠(yuǎn)程 TCP 的連接終止請(qǐng)求。

  • CLOSE-WAIT: 表示等待本地用戶(hù)的連接終止請(qǐng)求。

  • CLOSING: 表示等待來(lái)自遠(yuǎn)程 TCP 的連接終止請(qǐng)求確認(rèn)。

  • LAST-ACK: 表示等待先前發(fā)送給遠(yuǎn)程 TCP 的連接終止請(qǐng)求的確認(rèn)(包括對(duì)它的連接終止請(qǐng)求的確認(rèn))。

  • TIME-WAIT: 表示等待足夠的時(shí)間以確保遠(yuǎn)程 TCP 收到其連接終止請(qǐng)求的確認(rèn)。

  • CLOSED: 表示連接已經(jīng)關(guān)閉,無(wú)連接狀態(tài)。

上面 7 種狀態(tài)是 TCP 四次揮手,也就是斷開(kāi)鏈接所設(shè)計(jì)的。

TCP 的連接狀態(tài)會(huì)進(jìn)行各種切換,這些 TCP 連接的切換是根據(jù)事件進(jìn)行的,這些事件由用戶(hù)調(diào)用:OPEN、SEND、RECEIVE、CLOSE、ABORT 和 STATUS。涉及到 TCP 報(bào)文段的標(biāo)志有?SYN、ACK、RST 和 FIN?,當(dāng)然,還有超時(shí)。

我們下面加上 TCP 連接狀態(tài)后,再來(lái)看一下三次握手和四次揮手的過(guò)程。

三次握手建立連接

下圖畫(huà)出了 TCP 連接建立的過(guò)程。假設(shè)圖中左端是客戶(hù)端主機(jī),右端是服務(wù)端主機(jī),一開(kāi)始,兩端都處于CLOSED(關(guān)閉)狀態(tài)。

40張圖帶你搞懂TCP和UDP

  1. 服務(wù)端進(jìn)程準(zhǔn)備好接收來(lái)自外部的 TCP 連接,一般情況下是調(diào)用 bind、listen、socket 三個(gè)函數(shù)完成。這種打開(kāi)方式被認(rèn)為是?被動(dòng)打開(kāi)(passive open)。然后服務(wù)端進(jìn)程處于?LISTEN?狀態(tài),等待客戶(hù)端連接請(qǐng)求。

  2. 客戶(hù)端通過(guò)?connect?發(fā)起主動(dòng)打開(kāi)(active open),向服務(wù)器發(fā)出連接請(qǐng)求,請(qǐng)求中首部同步位 SYN = 1,同時(shí)選擇一個(gè)初始序號(hào) sequence ,簡(jiǎn)寫(xiě) seq = x。SYN 報(bào)文段不允許攜帶數(shù)據(jù),只消耗一個(gè)序號(hào)。此時(shí),客戶(hù)端進(jìn)入?SYN-SEND?狀態(tài)。

  3. 服務(wù)器收到客戶(hù)端連接后,,需要確認(rèn)客戶(hù)端的報(bào)文段。在確認(rèn)報(bào)文段中,把 SYN 和 ACK 位都置為 1 。確認(rèn)號(hào)是 ack = x + 1,同時(shí)也為自己選擇一個(gè)初始序號(hào) seq = y。請(qǐng)注意,這個(gè)報(bào)文段也不能攜帶數(shù)據(jù),但同樣要消耗掉一個(gè)序號(hào)。此時(shí),TCP 服務(wù)器進(jìn)入?SYN-RECEIVED(同步收到)?狀態(tài)。

  4. 客戶(hù)端在收到服務(wù)器發(fā)出的響應(yīng)后,還需要給出確認(rèn)連接。確認(rèn)連接中的 ACK 置為 1 ,序號(hào)為 seq = x + 1,確認(rèn)號(hào)為 ack = y + 1。TCP 規(guī)定,這個(gè)報(bào)文段可以攜帶數(shù)據(jù)也可以不攜帶數(shù)據(jù),如果不攜帶數(shù)據(jù),那么下一個(gè)數(shù)據(jù)報(bào)文段的序號(hào)仍是 seq = x + 1。這時(shí),客戶(hù)端進(jìn)入?ESTABLISHED (已連接)?狀態(tài)

  5. 服務(wù)器收到客戶(hù)的確認(rèn)后,也進(jìn)入?ESTABLISHED?狀態(tài)。

TCP 建立一個(gè)連接需要三個(gè)報(bào)文段,釋放一個(gè)連接卻需要四個(gè)報(bào)文段。

四次揮手

數(shù)據(jù)傳輸結(jié)束后,通信的雙方可以釋放連接。數(shù)據(jù)傳輸結(jié)束后的客戶(hù)端主機(jī)和服務(wù)端主機(jī)都處于 ESTABLISHED 狀態(tài),然后進(jìn)入釋放連接的過(guò)程。

40張圖帶你搞懂TCP和UDP

TCP 斷開(kāi)連接需要?dú)v經(jīng)的過(guò)程如下

  1. 客戶(hù)端應(yīng)用程序發(fā)出釋放連接的報(bào)文段,并停止發(fā)送數(shù)據(jù),主動(dòng)關(guān)閉 TCP 連接。客戶(hù)端主機(jī)發(fā)送釋放連接的報(bào)文段,報(bào)文段中首部 FIN 位置為 1 ,不包含數(shù)據(jù),序列號(hào)位 seq = u,此時(shí)客戶(hù)端主機(jī)進(jìn)入?FIN-WAIT-1(終止等待 1)?階段。

  2. 服務(wù)器主機(jī)接受到客戶(hù)端發(fā)出的報(bào)文段后,即發(fā)出確認(rèn)應(yīng)答報(bào)文,確認(rèn)應(yīng)答報(bào)文中 ACK = 1,生成自己的序號(hào)位 seq = v,ack = u + 1,然后服務(wù)器主機(jī)就進(jìn)入?CLOSE-WAIT(關(guān)閉等待)?狀態(tài),這個(gè)時(shí)候客戶(hù)端主機(jī) -> 服務(wù)器主機(jī)這條方向的連接就釋放了,客戶(hù)端主機(jī)沒(méi)有數(shù)據(jù)需要發(fā)送,此時(shí)服務(wù)器主機(jī)是一種半連接的狀態(tài),但是服務(wù)器主機(jī)仍然可以發(fā)送數(shù)據(jù)。

  3. 客戶(hù)端主機(jī)收到服務(wù)端主機(jī)的確認(rèn)應(yīng)答后,即進(jìn)入?FIN-WAIT-2(終止等待2)?的狀態(tài)。等待客戶(hù)端發(fā)出連接釋放的報(bào)文段。

  4. 當(dāng)服務(wù)器主機(jī)沒(méi)有數(shù)據(jù)發(fā)送后,應(yīng)用進(jìn)程就會(huì)通知 TCP 釋放連接。這時(shí)服務(wù)端主機(jī)會(huì)發(fā)出斷開(kāi)連接的報(bào)文段,報(bào)文段中 ACK = 1,序列號(hào) seq = w,因?yàn)樵谶@之間可能已經(jīng)發(fā)送了一些數(shù)據(jù),所以 seq 不一定等于 v + 1。ack = u + 1,在發(fā)送完斷開(kāi)請(qǐng)求的報(bào)文后,服務(wù)端主機(jī)就進(jìn)入了?LAST-ACK(最后確認(rèn))的階段。

  5. 客戶(hù)端收到服務(wù)端的斷開(kāi)連接請(qǐng)求后,客戶(hù)端需要作出響應(yīng),客戶(hù)端發(fā)出斷開(kāi)連接的報(bào)文段,在報(bào)文段中,ACK = 1, 序列號(hào) seq = u + 1,因?yàn)榭蛻?hù)端從連接開(kāi)始斷開(kāi)后就沒(méi)有再發(fā)送數(shù)據(jù),ack = w + 1,然后進(jìn)入到?TIME-WAIT(時(shí)間等待)?狀態(tài),請(qǐng)注意,這個(gè)時(shí)候 TCP 連接還沒(méi)有釋放。必須經(jīng)過(guò)時(shí)間等待的設(shè)置,也就是?2MSL?后,客戶(hù)端才會(huì)進(jìn)入?CLOSED?狀態(tài),時(shí)間 MSL 叫做最長(zhǎng)報(bào)文段壽命(Maximum Segment Lifetime)。

  6. 服務(wù)端主要收到了客戶(hù)端的斷開(kāi)連接確認(rèn)后,就會(huì)進(jìn)入 CLOSED 狀態(tài)。因?yàn)榉?wù)端結(jié)束 TCP 連接時(shí)間要比客戶(hù)端早,而整個(gè)連接斷開(kāi)過(guò)程需要發(fā)送四個(gè)報(bào)文段,因此釋放連接的過(guò)程也被稱(chēng)為四次揮手。

什么是 TIME-WAIT

我上面只是簡(jiǎn)單提到了一下 TIME-WAIT 狀態(tài)和 2MSL 是啥,下面來(lái)聊一下這兩個(gè)概念。

MSL?是 TCP 報(bào)文段可以存活或者駐留在網(wǎng)絡(luò)中的最長(zhǎng)時(shí)間。RFC 793 定義了 MSL 的時(shí)間是兩分鐘,但是具體的實(shí)現(xiàn)還要根據(jù)程序員來(lái)指定,一些實(shí)現(xiàn)采用了 30 秒的這個(gè)最大存活時(shí)間。

那么為什么要等待?2MSL?呢?

主要是因?yàn)閮蓚€(gè)理由

  • 為了保證最后一個(gè)響應(yīng)能夠到達(dá)服務(wù)器,因?yàn)樵谟?jì)算機(jī)網(wǎng)絡(luò)中,最后一個(gè) ACK 報(bào)文段可能會(huì)丟失,從而致使客戶(hù)端一直處于?LAST-ACK?狀態(tài)等待客戶(hù)端響應(yīng)。這時(shí)候服務(wù)器會(huì)重傳一次?FINACK?斷開(kāi)連接報(bào)文,客戶(hù)端接收后再重新確認(rèn),重啟定時(shí)器。如果客戶(hù)端不是 2MSL ,在客戶(hù)端發(fā)送 ACK 后直接關(guān)閉的話(huà),如果報(bào)文丟失,那么雙方主機(jī)會(huì)無(wú)法進(jìn)入 CLOSED 狀態(tài)。

  • 還可以防止已失效的報(bào)文段??蛻?hù)端在發(fā)送最后一個(gè) ACK 之后,再經(jīng)過(guò)經(jīng)過(guò) 2MSL,就可以使本鏈接持續(xù)時(shí)間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失。從而保證在關(guān)閉連接后不會(huì)有還在網(wǎng)絡(luò)中滯留的報(bào)文段去騷擾服務(wù)器。

這里注意一點(diǎn):在服務(wù)器發(fā)送了 FIN-ACK 之后,會(huì)立即啟動(dòng)超時(shí)重傳計(jì)時(shí)器。客戶(hù)端在發(fā)送最后一個(gè) ACK 之后會(huì)立即啟動(dòng)時(shí)間等待計(jì)時(shí)器。

說(shuō)好的 RST 呢

說(shuō)好的?RSTSYN、FIN?標(biāo)志用于連接的建立和關(guān)閉,那么 SYN 和 FIN 都現(xiàn)身了,那 RST 呢?也是啊,我們上面探討的都是一種理想的情況,就是客戶(hù)端服務(wù)器雙方都會(huì)接受傳輸報(bào)文段的情況,還有一種情況是當(dāng)主機(jī)收到 TCP 報(bào)文段后,其 IP 和端口號(hào)不匹配的情況。假設(shè)客戶(hù)端主機(jī)發(fā)送一個(gè)請(qǐng)求,而服務(wù)器主機(jī)經(jīng)過(guò) IP 和端口號(hào)的判斷后發(fā)現(xiàn)不是給這個(gè)服務(wù)器的,那么服務(wù)器就會(huì)發(fā)出一個(gè)?RST?特殊報(bào)文段給客戶(hù)端。

40張圖帶你搞懂TCP和UDP

因此,當(dāng)服務(wù)端發(fā)送一個(gè) RST 特殊報(bào)文段給客戶(hù)端的時(shí)候,它就會(huì)告訴客戶(hù)端沒(méi)有匹配的套接字連接,請(qǐng)不要再繼續(xù)發(fā)送了。

上面探討的是 TCP 的情況,那么 UDP 呢?

使用 UDP 作為傳輸協(xié)議后,如果套接字不匹配的話(huà),UDP 主機(jī)就會(huì)發(fā)送一個(gè)特殊的 ICMP 數(shù)據(jù)報(bào)。

SYN 洪泛攻擊

下面我們來(lái)討論一下什么是?SYN 洪泛攻擊

我們?cè)?TCP 的三次握手中已經(jīng)看到,服務(wù)器為了響應(yīng)一個(gè)收到的 SYN,分配并初始化變量連接和緩存,然后服務(wù)器發(fā)送一個(gè) SYNACK 作為響應(yīng),然后等待來(lái)自于客戶(hù)端的 ACK 報(bào)文。如果客戶(hù)端不發(fā)送 ACK 來(lái)完成最后一步的話(huà),那么這個(gè)連接就處在一個(gè)掛起的狀態(tài),也就是半連接狀態(tài)。

攻擊者通常在這種情況下發(fā)送大量的 TCP SYN 報(bào)文段,服務(wù)端繼續(xù)響應(yīng),但是每個(gè)連接都完不成三次握手的步驟。隨著 SYN 的不斷增加,服務(wù)器會(huì)不斷的為這些半開(kāi)連接分配資源,導(dǎo)致服務(wù)器的連接最終被消耗殆盡。這種攻擊也是屬于?Dos?攻擊的一種。

抵御這種攻擊的方式是使用?SYN cookie?,下面是它的工作流程介紹

  • 當(dāng)服務(wù)器收到一個(gè) SYN 報(bào)文段時(shí),它并不知道這個(gè)報(bào)文段是來(lái)自哪里,是來(lái)自攻擊者主機(jī)還是客戶(hù)端主機(jī)(雖然攻擊者也是客戶(hù)端,不過(guò)這么說(shuō)更便于區(qū)分) 。因此服務(wù)器不會(huì)為報(bào)文段生成一個(gè)半開(kāi)連接。與此相反,服務(wù)器生成一個(gè)初始的 TCP 序列號(hào),這個(gè)序列號(hào)是 SYN 報(bào)文段的源和目的 IP 地址與端口號(hào)這個(gè)四元組構(gòu)造的一個(gè)復(fù)雜的散列函數(shù),這個(gè)散列函數(shù)生成的 TCP 序列號(hào)就是?SYN Cookie,用于緩存 SYN 請(qǐng)求。然后,服務(wù)器會(huì)發(fā)送帶著 SYN Cookie 的 SYNACK 分組。有一點(diǎn)需要注意的是,服務(wù)器不會(huì)記憶這個(gè) Cookie 或 SYN 的其他狀態(tài)信息。

  • 如果客戶(hù)端不是攻擊者的話(huà),它就會(huì)返回一個(gè) ACK 報(bào)文段。當(dāng)服務(wù)器收到這個(gè) ACK 后,需要驗(yàn)證這個(gè) ACK 與 SYN 發(fā)送的是否相同,驗(yàn)證的標(biāo)準(zhǔn)就是確認(rèn)字段中的確認(rèn)號(hào)和序列號(hào),源和目的 IP 地址與端口號(hào)以及和散列函數(shù)的是否一致,散列函數(shù)的結(jié)果 + 1 是否和 SYNACK 中的確認(rèn)值相同。(大致是這樣,說(shuō)的不對(duì)還請(qǐng)讀者糾正) 。如果有興趣讀者可以自行深入了解。如果是合法的,服務(wù)器就會(huì)生成一個(gè)具有套接字的全開(kāi)連接。

  • 如果客戶(hù)端沒(méi)有返回 ACK,即認(rèn)為是攻擊者,那么這樣也沒(méi)關(guān)系,服務(wù)器沒(méi)有收到 ACK,不會(huì)分配變量和緩存資源,不會(huì)對(duì)服務(wù)器產(chǎn)生危害。

擁塞控制

有了 TCP 的窗口控制后,使計(jì)算機(jī)網(wǎng)絡(luò)中兩個(gè)主機(jī)之間不再是以單個(gè)數(shù)據(jù)段的形式發(fā)送了,而是能夠連續(xù)發(fā)送大量的數(shù)據(jù)包。然而,大量數(shù)據(jù)包同時(shí)也伴隨著其他問(wèn)題,比如網(wǎng)絡(luò)負(fù)載、網(wǎng)絡(luò)擁堵等問(wèn)題。TCP 為了防止這類(lèi)問(wèn)題的出現(xiàn),使用了?擁塞控制?機(jī)制,擁塞控制機(jī)制會(huì)在面臨網(wǎng)絡(luò)擁塞時(shí)遏制發(fā)送方的數(shù)據(jù)發(fā)送。

擁塞控制主要有兩種方法

  • 端到端的擁塞控制: 因?yàn)榫W(wǎng)絡(luò)層沒(méi)有為運(yùn)輸層擁塞控制提供顯示支持。所以即使網(wǎng)絡(luò)中存在擁塞情況,端系統(tǒng)也要通過(guò)對(duì)網(wǎng)絡(luò)行為的觀察來(lái)推斷。TCP 就是使用了端到端的擁塞控制方式。IP 層不會(huì)向端系統(tǒng)提供有關(guān)網(wǎng)絡(luò)擁塞的反饋信息。那么 TCP 如何推斷網(wǎng)絡(luò)擁塞呢?如果超時(shí)或者三次冗余確認(rèn)就被認(rèn)為是網(wǎng)絡(luò)擁塞,TCP 會(huì)減小窗口的大小,或者增加往返時(shí)延來(lái)避免。

  • 網(wǎng)絡(luò)輔助的擁塞控制: 在網(wǎng)絡(luò)輔助的擁塞控制中,路由器會(huì)向發(fā)送方提供關(guān)于網(wǎng)絡(luò)中擁塞狀態(tài)的反饋。這種反饋信息就是一個(gè)比特信息,它指示鏈路中的擁塞情況。

下圖描述了這兩種擁塞控制方式

40張圖帶你搞懂TCP和UDP

TCP 擁塞控制

如果你看到這里,那我就暫定認(rèn)為你了解了 TCP 實(shí)現(xiàn)可靠性的基礎(chǔ)了,那就是使用序號(hào)和確認(rèn)號(hào)。除此之外,另外一個(gè)實(shí)現(xiàn) TCP 可靠性基礎(chǔ)的就是 TCP 的擁塞控制。如果說(shuō)

TCP 所采用的方法是讓每一個(gè)發(fā)送方根據(jù)所感知到的網(wǎng)絡(luò)的擁塞程度來(lái)限制發(fā)出報(bào)文段的速率,如果 TCP 發(fā)送方感知到?jīng)]有什么擁塞,則 TCP 發(fā)送方會(huì)增加發(fā)送速率;如果發(fā)送方感知沿著路徑有阻塞,那么發(fā)送方就會(huì)降低發(fā)送速率。

但是這種方法有三個(gè)問(wèn)題

  1. TCP 發(fā)送方如何限制它向其他連接發(fā)送報(bào)文段的速率呢?

  2. 一個(gè) TCP 發(fā)送方是如何感知到網(wǎng)絡(luò)擁塞的呢?

  3. 當(dāng)發(fā)送方感知到端到端的擁塞時(shí),采用何種算法來(lái)改變其發(fā)送速率呢?

我們先來(lái)探討一下第一個(gè)問(wèn)題,TCP 發(fā)送方如何限制它向其他連接發(fā)送報(bào)文段的速率呢?

我們知道 TCP 是由接收緩存、發(fā)送緩存和變量(LastByteRead, rwnd,等)組成。發(fā)送方的 TCP 擁塞控制機(jī)制會(huì)跟蹤一個(gè)變量,即?擁塞窗口(congestion window)?的變量,擁塞窗口表示為?cwnd,用于限制 TCP 在接收到 ACK 之前可以發(fā)送到網(wǎng)絡(luò)的數(shù)據(jù)量。而接收窗口(rwnd)?是一個(gè)用于告訴接收方能夠接受的數(shù)據(jù)量。

一般來(lái)說(shuō),發(fā)送方未確認(rèn)的數(shù)據(jù)量不得超過(guò) cwnd 和 rwnd 的最小值,也就是

LastByteSent - LastByteAcked <= min(cwnd,rwnd)

由于每個(gè)數(shù)據(jù)包的往返時(shí)間是 RTT,我們假設(shè)接收端有足夠的緩存空間用于接收數(shù)據(jù),我們就不用考慮 rwnd 了,只專(zhuān)注于 cwnd,那么,該發(fā)送方的發(fā)送速率大概是?cwnd/RTT 字節(jié)/秒?。通過(guò)調(diào)節(jié) cwnd,發(fā)送方因此能調(diào)整它向連接發(fā)送數(shù)據(jù)的速率。

一個(gè) TCP 發(fā)送方是如何感知到網(wǎng)絡(luò)擁塞的呢?

這個(gè)我們上面討論過(guò),是 TCP 根據(jù)超時(shí)或者 3 個(gè)冗余 ACK 來(lái)感知的。

當(dāng)發(fā)送方感知到端到端的擁塞時(shí),采用何種算法來(lái)改變其發(fā)送速率呢??

這個(gè)問(wèn)題比較復(fù)雜,且容我娓娓道來(lái),一般來(lái)說(shuō),TCP 會(huì)遵循下面這幾種指導(dǎo)性原則

  • 如果在報(bào)文段發(fā)送過(guò)程中丟失,那就意味著網(wǎng)絡(luò)擁堵,此時(shí)需要適當(dāng)降低 TCP 發(fā)送方的速率。

  • 一個(gè)確認(rèn)報(bào)文段指示發(fā)送方正在向接收方傳遞報(bào)文段,因此,當(dāng)對(duì)先前未確認(rèn)報(bào)文段的確認(rèn)到達(dá)時(shí),能夠增加發(fā)送方的速率。為啥呢?因?yàn)槲创_認(rèn)的報(bào)文段到達(dá)接收方也就表示著網(wǎng)絡(luò)不擁堵,能夠順利到達(dá),因此發(fā)送方擁塞窗口長(zhǎng)度會(huì)變大,所以發(fā)送速率會(huì)變快

  • 帶寬探測(cè),帶寬探測(cè)說(shuō)的是 TCP 可以通過(guò)調(diào)節(jié)傳輸速率來(lái)增加/減小 ACK 到達(dá)的次數(shù),如果出現(xiàn)丟包事件,就會(huì)減小傳輸速率。因此,為了探測(cè)擁塞開(kāi)始出現(xiàn)的頻率, TCP 發(fā)送方應(yīng)該增加它的傳輸速率。然后慢慢使傳輸速率降低,進(jìn)而再次開(kāi)始探測(cè),看看擁塞開(kāi)始速率是否發(fā)生了變化。

在了解完 TCP 擁塞控制后,下面我們就該聊一下 TCP 的?擁塞控制算法(TCP congestion control algorithm)?了。TCP 擁塞控制算法主要包含三個(gè)部分:慢啟動(dòng)、擁塞避免、快速恢復(fù),下面我們依次來(lái)看一下

慢啟動(dòng)

當(dāng)一條 TCP 開(kāi)始建立連接時(shí),cwnd 的值就會(huì)初始化為一個(gè) MSS 的較小值。這就使得初始發(fā)送速率大概是?MSS/RTT 字節(jié)/秒?,比如要傳輸 1000 字節(jié)的數(shù)據(jù),RTT 為 200 ms ,那么得到的初始發(fā)送速率大概是 40 kb/s 。實(shí)際情況下可用帶寬要比這個(gè) MSS/RTT 大得多,因此 TCP 想要找到最佳的發(fā)送速率,可以通過(guò)?慢啟動(dòng)(slow-start)?的方式,在慢啟動(dòng)的方式中,cwnd 的值會(huì)初始化為 1 個(gè) MSS,并且每次傳輸報(bào)文確認(rèn)后就會(huì)增加一個(gè) MSS,cwnd 的值會(huì)變?yōu)?2 個(gè) MSS,這兩個(gè)報(bào)文段都傳輸成功后每個(gè)報(bào)文段 + 1,會(huì)變?yōu)?4 個(gè) MSS,依此類(lèi)推,每成功一次 cwnd 的值就會(huì)翻倍。如下圖所示

40張圖帶你搞懂TCP和UDP

發(fā)送速率不可能會(huì)一直增長(zhǎng),增長(zhǎng)總有結(jié)束的時(shí)候,那么何時(shí)結(jié)束呢?慢啟動(dòng)通常會(huì)使用下面這幾種方式結(jié)束發(fā)送速率的增長(zhǎng)。

  • 如果在慢啟動(dòng)的發(fā)送過(guò)程出現(xiàn)丟包的情況,那么 TCP 會(huì)將發(fā)送方的 cwnd 設(shè)置為 1 并重新開(kāi)始慢啟動(dòng)的過(guò)程,此時(shí)會(huì)引入一個(gè)?ssthresh(慢啟動(dòng)閾值)?的概念,它的初始值就是產(chǎn)生丟包的 cwnd 的值 / 2,即當(dāng)檢測(cè)到擁塞時(shí),ssthresh 的值就是窗口值的一半。

  • 第二種方式是直接和 ssthresh 的值相關(guān)聯(lián),因?yàn)楫?dāng)檢測(cè)到擁塞時(shí),ssthresh 的值就是窗口值的一半,那么當(dāng) cwnd > ssthresh 時(shí),每次翻番都可能會(huì)出現(xiàn)丟包,所以最好的方式就是 cwnd 的值 = ssthresh ,這樣 TCP 就會(huì)轉(zhuǎn)為擁塞控制模式,結(jié)束慢啟動(dòng)。

  • 慢啟動(dòng)結(jié)束的最后一種方式就是如果檢測(cè)到 3 個(gè)冗余 ACK,TCP 就會(huì)執(zhí)行一種快速重傳并進(jìn)入恢復(fù)狀態(tài)。

擁塞避免

當(dāng) TCP 進(jìn)入擁塞控制狀態(tài)后,cwnd 的值就等于擁塞時(shí)值的一半,也就是 ssthresh 的值。所以,無(wú)法每次報(bào)文段到達(dá)后都將 cwnd 的值再翻倍。而是采用了一種相對(duì)保守的方式,每次傳輸完成后只將 cwnd 的值增加一個(gè) MSS,比如收到了 10 個(gè)報(bào)文段的確認(rèn),但是 cwnd 的值只增加一個(gè) MSS。這是一種線(xiàn)性增長(zhǎng)模式,它也會(huì)有增長(zhǎng)逾值,它的增長(zhǎng)逾值和慢啟動(dòng)一樣,如果出現(xiàn)丟包,那么 cwnd 的值就是一個(gè) MSS,ssthresh 的值就等于 cwnd 的一半;或者是收到 3 個(gè)冗余的 ACK 響應(yīng)也能停止 MSS 增長(zhǎng)。如果 TCP 將 cwnd 的值減半后,仍然會(huì)收到 3 個(gè)冗余 ACK,那么就會(huì)將 ssthresh 的值記錄為 cwnd 值的一半,進(jìn)入?快速恢復(fù)?狀態(tài)。

快速恢復(fù)

在快速恢復(fù)中,對(duì)于使 TCP 進(jìn)入快速恢復(fù)狀態(tài)缺失的報(bào)文段,對(duì)于每個(gè)收到的冗余 ACK,cwnd 的值都會(huì)增加一個(gè) MSS 。當(dāng)對(duì)丟失報(bào)文段的一個(gè) ACK 到達(dá)時(shí),TCP 在降低 cwnd 后進(jìn)入擁塞避免狀態(tài)。如果在擁塞控制狀態(tài)后出現(xiàn)超時(shí),那么就會(huì)遷移到慢啟動(dòng)狀態(tài),cwnd 的值被設(shè)置為 1 個(gè) MSS,ssthresh 的值設(shè)置為 cwnd 的一半。

到這里,我相信你定會(huì)收獲。

特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒(méi)關(guān)注的小伙伴,可以長(zhǎng)按關(guān)注一下:

40張圖帶你搞懂TCP和UDP

40張圖帶你搞懂TCP和UDP

40張圖帶你搞懂TCP和UDP

長(zhǎng)按訂閱更多精彩▼

40張圖帶你搞懂TCP和UDP

如有收獲,點(diǎn)個(gè)在看,誠(chéng)摯感謝

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉