整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          你知道 HTTP 是如何使用 TCP 連接的嗎?今天我就來(lái)告訴你

          、HTTP 是如何使用 TCP 連接的;

          世界上幾乎所有的 HTTP 通信都是由 TCP/IP 承載的,TCP/IP 是全球計(jì)算機(jī)及網(wǎng)絡(luò)設(shè)備都 在使用的一種常用的分組交換網(wǎng)絡(luò)分層協(xié)議集。客戶端應(yīng)用程序可以打開一條 TCP/IP 連 接,連接到可能運(yùn)行在世界任何地方的服務(wù)器應(yīng)用程序。一旦連接建立起來(lái)了,在客戶端 和服務(wù)器的計(jì)算機(jī)之間交換的報(bào)文就永遠(yuǎn)不會(huì)丟失、受損或失序。

          盡管報(bào)文不會(huì)丟失或受損,但如果計(jì)算機(jī)或網(wǎng)絡(luò)崩潰了,客戶端和服務(wù)器之間的通信仍然會(huì)被斷開。在這種情況下, 會(huì)通知客戶端和服務(wù)器通信中斷了。

          當(dāng)瀏覽器收到一個(gè) URL 的時(shí)候,會(huì)執(zhí)行幾個(gè)相對(duì)應(yīng)的步驟,如下

          1. 瀏覽器解析出主機(jī)名;
          2. 瀏覽器查詢主機(jī)名的 IP 地址;
          3. 瀏覽器獲得端口號(hào);
          4. 瀏覽器發(fā)起對(duì)該 IP 地址對(duì)應(yīng)端口號(hào)的鏈接;
          5. 瀏覽器向服務(wù)器發(fā)送一條 HTTP GET報(bào)文;
          6. 瀏覽器從服務(wù)器讀取 HTTP 相應(yīng)報(bào)文;
          7. 瀏覽器關(guān)閉連接;

          1.1、TCP 連接的基本知識(shí)

          TCP 是可靠的數(shù)據(jù)管道

          TCP 會(huì)按序、無(wú)差錯(cuò)地承載 HTTP 數(shù)據(jù),TCP 為 HTTP 提供了一條可靠的比特傳輸管道。從 TCP 連接一端填入的字節(jié)會(huì)從另一端 以原有的順序、正確地傳送出來(lái)。

          TCP 流是分段的、由 IP 分組傳送

          TCP 的數(shù)據(jù)是通過(guò)名為 IP 分組(或 IP 數(shù)據(jù)報(bào))的小數(shù)據(jù)塊來(lái)發(fā)送的。

          這樣的話,如圖 HTTP 就是 “HTTP over TCP over IP” 這個(gè)“協(xié)議棧”中的最頂層了。其安全版本 HTTPS 就是在 HTTP 和 TCP 之間插入了一個(gè)(稱為 TLS 或 SSL 的)密碼加密層(安全層),就是在圖中的右半部分。

          HTTP 要傳送一條報(bào)文時(shí),會(huì)以流的形式將報(bào)文數(shù)據(jù)的內(nèi)容通過(guò)一條打開的 TCP 連接按 序傳輸。TCP 收到數(shù)據(jù)流之后,會(huì)將數(shù)據(jù)流砍成被稱作段的小數(shù)據(jù)塊,并將段封裝在 IP 分組中,通過(guò)因特網(wǎng)進(jìn)行傳輸,如下圖中大家看到的內(nèi)容:

          每個(gè) TCP 段都是由 IP 分組承載,從一個(gè) IP 地址發(fā)送到另一個(gè) IP 地址的。

          而每個(gè) IP 分組中都包括:

          • 一個(gè) IP 分組首部(通常為 20 字節(jié));
          • 一個(gè) TCP 段首部(通常為 20 字節(jié));
          • 一個(gè) TCP 數(shù)據(jù)塊(0 個(gè)或多個(gè)字節(jié))。

          IP 首部包含了源和目的 IP 地址、長(zhǎng)度和其他一些標(biāo)記。TCP 段的首部包含了 TCP 端口 號(hào)、TCP 控制標(biāo)記,以及用于數(shù)據(jù)排序和完整性檢查的一些數(shù)字值。

          保持 TCP 連接的持續(xù)不間斷地運(yùn)行

          在任意時(shí)刻計(jì)算機(jī)都可以有幾條 TCP 連接處于打開狀態(tài)。TCP 是通過(guò)端口號(hào)來(lái)保持所有 這些連接的正確運(yùn)行的。端口號(hào)和雇員使用的電話分機(jī)號(hào)很類似。

          這就和我之前舉得例子是一樣的,公司的總機(jī)和你自己的座機(jī)一樣,公司的總機(jī)號(hào)碼能將你接到前臺(tái),而分機(jī)號(hào) 可以將你接到正確的雇員位置一樣,IP 地址可以將你連接到正確的計(jì)算機(jī),而端口號(hào)則 可以將你連接到正確的應(yīng)用程序上去。TCP 連接是通過(guò) 4 個(gè)值來(lái)識(shí)別的:

          源IP 地址、源端口號(hào)、目的IP 地址、目的端口號(hào)

          這 4 個(gè)值一起唯一地定義了一條連接。兩條不同的 TCP 連接不能擁有 4 個(gè)完全相同的地 址組件值(但不同連接的部分組件可以擁有相同的值)。

          這里需要我們注意的是,有些連接共享了相同的目的端口號(hào),有些連接使用了相同的源 IP 地址,有些使用了相同的目的 IP 地址,但沒有兩個(gè)不同連接所有的 4 個(gè)值都一樣。

          TCP 套接字

          操作系統(tǒng)提供了一些操縱其 TCP 連接的工具。為了更具體地說(shuō)明問(wèn)題,我們來(lái)看一個(gè) TCP 編程接口,這些套接字我就不一一介紹了,我給大家一個(gè)表格,大家可以理解一下

          套接字API調(diào)用描 述s = socket()創(chuàng)建一個(gè)新的、未命名、未關(guān)聯(lián)的套接字bind(s,)向套接字賦一個(gè)本地端口號(hào)和接口connect(s,)創(chuàng)建一條連接本地套接字與遠(yuǎn)程主機(jī)及端口的連接listen(s,...)標(biāo)識(shí)一個(gè)本地套接字,使其可以合法接受連接s2 = accept(s)等待某人建立一條到本地端口的連接

          套接字 API 允許用戶創(chuàng)建 TCP 的端點(diǎn)數(shù)據(jù)結(jié)構(gòu),將這些端點(diǎn)與遠(yuǎn)程服務(wù)器的 TCP 端點(diǎn)進(jìn) 行連接,并對(duì)數(shù)據(jù)流進(jìn)行讀寫。TCP API 隱藏了所有底層網(wǎng)絡(luò)協(xié)議的握手細(xì)節(jié),以及 TCP 數(shù)據(jù)流與 IP 分組之間的分段和重裝細(xì)節(jié)。

          TCP 客戶端和服務(wù)器是如何通過(guò) TCP 套接字接口進(jìn)行通信的


          上圖中說(shuō)明了可以怎樣通過(guò)套接字 API 來(lái)凸顯客戶端和服務(wù)器在實(shí)現(xiàn) HTTP 事務(wù)時(shí)所應(yīng)執(zhí)行的步驟。

          2、TCP 連接的握手

          TCP 連接握手需要經(jīng)過(guò)以下幾個(gè)步驟。如圖所示:

          請(qǐng)求新的 TCP 連接時(shí),客戶端要向服務(wù)器發(fā)送一個(gè)小的 TCP 分組(通常是 40 ~ 60 個(gè)字節(jié))。這個(gè)分組中設(shè)置了一個(gè)特殊的 SYN 標(biāo)記,說(shuō)明這是一個(gè)連接請(qǐng)求。

          1. 如果服務(wù)器接受了連接,就會(huì)對(duì)一些連接參數(shù)進(jìn)行計(jì)算,并向客戶端回送一個(gè) TCP 分組,這個(gè)分組中的 SYN 和 ACK 標(biāo)記都被置位,說(shuō)明連接請(qǐng)求已被接受。
          2. 最后,客戶端向服務(wù)器回送一條確認(rèn)信息,通知它連接已成功建立

          我們永遠(yuǎn)不會(huì)看到這些分組——這些分組都由 TCP/IP 軟件管理,對(duì)其是不可見 的。HTTP 程序員看到的只是創(chuàng)建 TCP 連接時(shí)存在的時(shí)延。

          在這里我們需要注意的就是 TCP 連接的握手時(shí)延,通常 HTTP 事務(wù)都不會(huì)交換太多數(shù)據(jù),此時(shí),SYN/SYN+ACK 握手(參見圖中的 a 段 和圖中的 b 段)會(huì)產(chǎn)生一個(gè)可測(cè)量的時(shí)延。TCP 連接的 ACK 分組(參見圖中的 c 段)通常都足夠大,可以承載整個(gè) HTTP 請(qǐng)求報(bào)文,而且很多 HTTP 服務(wù)器響應(yīng)報(bào)文都可 以放入一個(gè) IP 分組 中去(比如,響應(yīng)是包含了裝飾性圖片的小型 HTML 文件,或者是對(duì)瀏覽器高速緩存請(qǐng)求產(chǎn)生的 304 Not Modified 響應(yīng))。

          TCP 慢啟動(dòng)

          TCP 數(shù)據(jù)傳輸?shù)男阅苓€取決于 TCP 連接的使用期(age)。TCP 連接會(huì)隨著時(shí)間進(jìn)行自 我“調(diào)諧”,起初會(huì)限制連接的最大速度,如果數(shù)據(jù)成功傳輸,會(huì)隨著時(shí)間的推移提高傳輸 的速度。這種調(diào)諧被稱為 TCP 慢啟動(dòng)(slow start),用于防止因特網(wǎng)的突然過(guò)載和擁 塞。

          TCP 慢啟動(dòng)限制了一個(gè) TCP 端點(diǎn)在任意時(shí)刻可以傳輸?shù)姆纸M數(shù)。簡(jiǎn)單來(lái)說(shuō),每成功接收 一個(gè)分組,發(fā)送端就有了發(fā)送另外兩個(gè)分組的權(quán)限。如果某個(gè) HTTP 事務(wù)有大量數(shù)據(jù)要發(fā) 送,是不能一次將所有分組都發(fā)送出去的。必須發(fā)送一個(gè)分組,等待確認(rèn);然后可以發(fā)送 兩個(gè)分組,每個(gè)分組都必須被確認(rèn),這樣就可以發(fā)送四個(gè)分組了,以此類推。這種方式被 稱為“打開擁塞窗口”。

          由于存在這種擁塞控制特性,所以新連接的傳輸速度會(huì)比已經(jīng)交換過(guò)一定量數(shù)據(jù)的、“已 調(diào)諧”連接慢一些。由于已調(diào)諧連接要更快一些,所以 HTTP 中有一些可以重用現(xiàn)存連接 的工具。

          3、HTTP 連接的處理

          前面我們說(shuō)了 TCP 連接,我們重新來(lái)分析一下 HTTP ,之前我也說(shuō)過(guò)在 HTTP 1.0的時(shí)候和1.1之后,有 Keep-Alive ,關(guān)于 Keep-Alive 不懂的請(qǐng)翻看前面的公眾號(hào)的文章內(nèi)容,接下來(lái)我分幾個(gè)內(nèi)容給大家講述 HTTP 對(duì)連接上的處理。

          • 并行連接:通過(guò)多條 TCP 連接發(fā)起并發(fā)的 HTTP 請(qǐng)求。
          • 持久連接:重用 TCP 連接,以消除連接及關(guān)閉時(shí)延。
          • 管道化連接:通過(guò)共享的 TCP 連接發(fā)起并發(fā)的 HTTP 請(qǐng)求。

          我們來(lái)看一下串行:

          每個(gè)事務(wù)都需要(串行地建立)一條 新的連接,那么連接時(shí)延和慢啟動(dòng)時(shí)延就會(huì)疊加起來(lái)

          并行連接就是說(shuō) HTTP 允許客戶端打開多條連接,并行的去執(zhí)行多個(gè) HTTP 的事務(wù),就會(huì)出現(xiàn)多條線路平行的情況。

          其實(shí)并行連接并沒有說(shuō)是頁(yè)面的傳輸速度,是因?yàn)槎鄠€(gè)對(duì)象同時(shí)在進(jìn)展,所以,他的速度要比疊加起來(lái),讓你在感覺上快不少。

          持久連接

          HTTP 1.1 允許 HTTP 設(shè)備在事務(wù)處理結(jié)束之后 將 TCP 連接保持在打開狀態(tài),以便為未來(lái)的 HTTP 請(qǐng)求重用現(xiàn)存的連接。在事務(wù)處理結(jié)束之后仍然保持在打開狀態(tài)的 TCP 連接被稱為持久連接。非持久連接會(huì)在每個(gè)事務(wù)結(jié)束之后關(guān)閉。持久連接會(huì)在不同事務(wù)之間保持打開狀態(tài),直到客戶端或服務(wù)器決定將其關(guān)閉為止。

          管道化連接(也有人稱之為管線化)

          HTTP/1.1 允許在持久連接上可選地使用請(qǐng)求管道。這是相對(duì)于 keep-alive 連接的又一性能優(yōu)化。在響應(yīng)到達(dá)之前,可以將多條請(qǐng)求放入隊(duì)列。當(dāng)?shù)谝粭l請(qǐng)求通過(guò)網(wǎng)絡(luò)流向地球另一端的服務(wù)器時(shí),第二條和第三條請(qǐng)求也可以開始發(fā)送了。在高時(shí)延網(wǎng)絡(luò)條件下,這樣做可以降低網(wǎng)絡(luò)的環(huán)回時(shí)間,提高性能。

          其實(shí)管道化說(shuō)白了就是 傳送過(guò)程中不需先等待服務(wù)端的回應(yīng),然后又發(fā)了幾條,瀏覽器將 HTTP 要求大批提交可大幅縮短頁(yè)面的加載時(shí)間,特別是在傳輸延遲(lag/latency)較高的情況下(如衛(wèi)星連接)。此技術(shù)之關(guān)鍵在于多個(gè) HTTP 的要求消息可以同時(shí)塞入一個(gè) TCP 分組中,所以只提交一個(gè)分組即可同時(shí)發(fā)出多個(gè)要求,借此可減少網(wǎng)絡(luò)上多余的分組并降低線路負(fù)載。

          關(guān)注我,后續(xù)更多干貨奉上!

          Modbus由MODICON公司于1979年開發(fā),是一種工業(yè)現(xiàn)場(chǎng)總線協(xié)議標(biāo)準(zhǔn)。1996年施耐德公司推出基于以太網(wǎng)TCP/IP的Modbus協(xié)議:ModbusTCP

          Modbus協(xié)議是一項(xiàng)應(yīng)用層報(bào)文傳輸協(xié)議,包括ASCII、RTU、TCP三種報(bào)文類型。

          標(biāo)準(zhǔn)的Modbus協(xié)議物理層接口有RS232、RS422、RS485和以太網(wǎng)接口,采用master/slave方式通信。


          ModbusTCP數(shù)據(jù)幀

          ModbusTCP的數(shù)據(jù)幀可分為兩部分:MBAP+PDU


          報(bào)文頭MBAP

          MBAP為報(bào)文頭,長(zhǎng)度為7字節(jié),組成如下:

          事務(wù)處理標(biāo)識(shí)

          協(xié)議標(biāo)識(shí)

          長(zhǎng)度

          單元標(biāo)識(shí)符

          2字節(jié)

          2字節(jié)

          2字節(jié)

          1字節(jié)


          內(nèi)容

          解釋

          事務(wù)處理標(biāo)識(shí)

          可以理解為報(bào)文的序列號(hào),一般每次通信之后就要加1以區(qū)別不同的通信數(shù)據(jù)報(bào)文。

          協(xié)議標(biāo)識(shí)符

          00 00表示ModbusTCP協(xié)議。

          長(zhǎng)度

          表示接下來(lái)的數(shù)據(jù)長(zhǎng)度,單位為字節(jié)。

          單元標(biāo)識(shí)符

          可以理解為設(shè)備地址。


          幀結(jié)構(gòu)PDU

          PDU由功能碼+數(shù)據(jù)組成。功能碼為1字節(jié),數(shù)據(jù)長(zhǎng)度不定,由具體功能決定。

          功能碼

          Modbus的操作對(duì)象有四種:線圈、離散輸入、保持寄存器、輸入寄存器。

          對(duì)象

          含義

          線圈

          PLC的輸出位,開關(guān)量,在Modbus中可讀可寫

          離散量

          PLC的輸入位,開關(guān)量,在Modbus中只讀

          輸入寄存器

          PLC中只能從模擬量輸入端改變的寄存器,在Modbus中只讀

          保持寄存器

          PLC中用于輸出模擬量信號(hào)的寄存器,在Modbus中可讀可寫

          根據(jù)對(duì)象的不同,Modbus的功能碼有:

          功能碼

          含義

          0x01

          讀線圈

          0x05

          寫單個(gè)線圈

          0x0F

          寫多個(gè)線圈

          0x02

          讀離散量輸入

          0x04

          讀輸入寄存器

          0x03

          讀保持寄存器

          0x06

          寫單個(gè)保持寄存器

          0x10

          寫多個(gè)保持寄存器

          說(shuō)明更詳細(xì)的表

          代碼

          中文名稱

          英文名

          位操作/字操作

          操作數(shù)量

          01

          讀線圈狀態(tài)

          READ COIL STATUS

          位操作

          單個(gè)或多個(gè)

          02

          讀離散輸入狀態(tài)

          READ INPUT STATUS

          位操作

          單個(gè)或多個(gè)

          03

          讀保持寄存器

          READ HOLDING REGISTER

          字操作

          單個(gè)或多個(gè)

          04

          讀輸入寄存器

          READ INPUT REGISTER

          字操作

          單個(gè)或多個(gè)

          05

          寫線圈狀態(tài)

          WRITE SINGLE COIL

          位操作

          單個(gè)

          06

          寫單個(gè)保持寄存器

          WRITE SINGLE REGISTER

          字操作

          單個(gè)

          15

          寫多個(gè)線圈

          WRITE MULTIPLE COIL

          位操作

          多個(gè)

          16

          寫多個(gè)保持寄存器

          WRITE MULTIPLE REGISTER

          字操作

          多個(gè)


          PDU詳細(xì)結(jié)構(gòu)

          0x01:讀線圈

          在從站中讀1~2000個(gè)連續(xù)線圈狀態(tài),ON=1,OFF=0

          • 請(qǐng)求:MBAP 功能碼 起始地址H 起始地址L 數(shù)量H 數(shù)量L(共12字節(jié))
          • 響應(yīng):MBAP 功能碼 數(shù)據(jù)長(zhǎng)度 數(shù)據(jù)(一個(gè)地址的數(shù)據(jù)為1位)
          • 如:在從站0x01中,讀取開始地址為0x0002的線圈數(shù)據(jù),讀0x0008位
            00 01 00 00 00 06 01 01 00 02 00 08
          • 回:數(shù)據(jù)長(zhǎng)度為0x01個(gè)字節(jié),數(shù)據(jù)為0x01,第一個(gè)線圈為ON,其余為OFF
            00 01 00 00 00 04 01 01 01 01

          0x05:寫單個(gè)線圈

          將從站中的一個(gè)輸出寫成ON或OFF,0xFF00請(qǐng)求輸出為ON,0x000請(qǐng)求輸出為OFF

          • 請(qǐng)求:MBAP 功能碼 輸出地址H 輸出地址L 輸出值H 輸出值L(共12字節(jié))
          • 響應(yīng):MBAP 功能碼 輸出地址H 輸出地址L 輸出值H 輸出值L(共12字節(jié))
          • 如:將地址為0x0003的線圈設(shè)為ON
            00 01 00 00 00 06 01 05 00 03 FF 00
          • 回:寫入成功
            00 01 00 00 00 06 01 05 00 03 FF 00

          0x0F:寫多個(gè)線圈

          將一個(gè)從站中的一個(gè)線圈序列的每個(gè)線圈都強(qiáng)制為ON或OFF,數(shù)據(jù)域中置1的位請(qǐng)求相應(yīng)輸出位ON,置0的位請(qǐng)求響應(yīng)輸出為OFF

          • 請(qǐng)求:MBAP 功能碼 起始地址H 起始地址L 輸出數(shù)量H 輸出數(shù)量L 字節(jié)長(zhǎng)度 輸出值H 輸出值L
          • 響應(yīng):MBAP 功能碼 起始地址H 起始地址L 輸出數(shù)量H 輸出數(shù)量L

          0x02:讀離散量輸入

          從一個(gè)從站中讀1~2000個(gè)連續(xù)的離散量輸入狀態(tài)

          • 請(qǐng)求:MBAP 功能碼 起始地址H 起始地址L 數(shù)量H 數(shù)量L(共12字節(jié))
          • 響應(yīng):MBAP 功能碼 數(shù)據(jù)長(zhǎng)度 數(shù)據(jù)(長(zhǎng)度:9+ceil(數(shù)量/8))
          • 如:從地址0x0000開始讀0x0012個(gè)離散量輸入
            00 01 00 00 00 06 01 02 00 00 00 12
          • 回:數(shù)據(jù)長(zhǎng)度為0x03個(gè)字節(jié),數(shù)據(jù)為0x01 04 00,表示第一個(gè)離散量輸入和第11個(gè)離散量輸入為ON,其余為OFF
            00 01 00 00 00 06 01 02 03 01 04 00

          0x04:讀輸入寄存器

          從一個(gè)遠(yuǎn)程設(shè)備中讀1~2000個(gè)連續(xù)輸入寄存器

          • 請(qǐng)求:MBAP 功能碼 起始地址H 起始地址L 寄存器數(shù)量H 寄存器數(shù)量L(共12字節(jié))
          • 響應(yīng):MBAP 功能碼 數(shù)據(jù)長(zhǎng)度 寄存器數(shù)據(jù)(長(zhǎng)度:9+寄存器數(shù)量×2)
          • 如:讀起始地址為0x0002,數(shù)量為0x0005的寄存器數(shù)據(jù)
            00 01 00 00 00 06 01 04 00 02 00 05
          • 回:數(shù)據(jù)長(zhǎng)度為0x0A,第一個(gè)寄存器的數(shù)據(jù)為0x0c,其余為0x00
            00 01 00 00 00 0D 01 04 0A 00 0C 00 00 00 00 00 00 00 00

          0x03:讀保持寄存器

          從遠(yuǎn)程設(shè)備中讀保持寄存器連續(xù)塊的內(nèi)容

          • 請(qǐng)求:MBAP 功能碼 起始地址H 起始地址L 寄存器數(shù)量H 寄存器數(shù)量L(共12字節(jié))
          • 響應(yīng):MBAP 功能碼 數(shù)據(jù)長(zhǎng)度 寄存器數(shù)據(jù)(長(zhǎng)度:9+寄存器數(shù)量×2)
          • 如:起始地址是0x0000,寄存器數(shù)量是 0x0003
            00 01 00 00 00 06 01 03 00 00 00 03
          • 回:數(shù)據(jù)長(zhǎng)度為0x06,第一個(gè)寄存器的數(shù)據(jù)為0x21,其余為0x00
            00 01 00 00 00 09 01 03 06 00 21 00 00 00 00

          0x06:寫單個(gè)保持寄存器

          在一個(gè)遠(yuǎn)程設(shè)備中寫一個(gè)保持寄存器

          • 請(qǐng)求:MBAP 功能碼 寄存器地址H 寄存器地址L 寄存器值H 寄存器值L(共12字節(jié))
          • 響應(yīng):MBAP 功能碼 寄存器地址H 寄存器地址L 寄存器值H 寄存器值L(共12字節(jié))
          • 如:向地址是0x0000的寄存器寫入數(shù)據(jù)0x000A
            00 01 00 00 00 06 01 06 00 00 00 0A
          • 回:寫入成功
            00 01 00 00 00 06 01 06 00 00 00 0A

          0x10:寫多個(gè)保持寄存器

          在一個(gè)遠(yuǎn)程設(shè)備中寫連續(xù)寄存器塊(1~123個(gè)寄存器)

          • 請(qǐng)求:MBAP 功能碼 起始地址H 起始地址L 寄存器數(shù)量H 寄存器數(shù)量L 字節(jié)長(zhǎng)度 寄存器值(13+寄存器數(shù)量×2)
          • 響應(yīng):MBAP 功能碼 起始地址H 起始地址L 寄存器數(shù)量H 寄存器數(shù)量L(共12字節(jié))
          • 如:向起始地址為0x0000,數(shù)量為0x0001的寄存器寫入數(shù)據(jù),數(shù)據(jù)長(zhǎng)度為0x02,數(shù)據(jù)為0x000F
            00 01 00 00 00 09 01 10 00 00 00 01 02 00 0F
          • 回:寫入成功
            00 01 00 00 00 06 01 10 00 00 00 01


          Modbus TCP 示例報(bào)文

          ModBusTcp與串行鏈路Modbus的數(shù)據(jù)域是一致的,具體數(shù)據(jù)域可以參考串行Modbus。這里給出幾個(gè)ModbusTcp的鏈路解析說(shuō)明,輔助新人分析報(bào)文。

          功能碼 0x10:寫多個(gè)保持寄存器,上面2個(gè)圖片都寫錯(cuò)了


          ModbusTCP通信

          通信方式

          Modbus設(shè)備可分為主站(poll)和從站(slave)。主站只有一個(gè),從站有多個(gè),主站向各從站發(fā)送請(qǐng)求幀,從站給予響應(yīng)。在使用TCP通信時(shí),主站為client端,主動(dòng)建立連接;從站為server端,等待連接。

          • 主站請(qǐng)求:功能碼+數(shù)據(jù)
          • 從站正常響應(yīng):請(qǐng)求功能碼+響應(yīng)數(shù)據(jù)
          • 從站異常響應(yīng):異常功能碼+異常碼,其中異常功能碼即將請(qǐng)求功能碼的最高有效位置1,異常碼指示差錯(cuò)類型
          • 注意:需要超時(shí)管理機(jī)制,避免無(wú)期限的等待可能不出現(xiàn)的應(yīng)答

          IANA(Internet Assigned Numbers Authority,互聯(lián)網(wǎng)編號(hào)分配管理機(jī)構(gòu))給Modbus協(xié)議賦予TCP端口號(hào)為502,這是目前在儀表與自動(dòng)化行業(yè)中唯一分配到的端口號(hào)。

          通信過(guò)程

          1. connect 建立TCP連接
          2. 準(zhǔn)備Modbus報(bào)文
          3. 使用send命令發(fā)送報(bào)文
          4. 在同一連接下等待應(yīng)答
          5. 使用recv命令讀取報(bào)文,完成一次數(shù)據(jù)交換
          6. 通信任務(wù)結(jié)束時(shí),關(guān)閉TCP連接


          仿真軟件

          • Modbus poll 和Modbus slave是一組Modbus仿真軟件,可以實(shí)現(xiàn)Modbus RTU、TCP、串口仿真等。
          • 仿真軟件網(wǎng)址:https://modbustools.com/download.html
          • 在ModbusTCP中,Modbus poll 作為客戶端請(qǐng)求數(shù)據(jù),Modbus slave 作為服務(wù)器端處理請(qǐng)求。
          • 使用c語(yǔ)言編寫客戶端連接Modbus slave時(shí),注意數(shù)據(jù)格式,一條指令一次性發(fā)出,否則連接會(huì)出錯(cuò)。
          • 使用軟件時(shí),需要指定功能碼,在setup->slave definition或者poll definition中進(jìn)行設(shè)置。
            – slave ID:從站編號(hào)(事務(wù)標(biāo)識(shí)符)
            – function:功能碼,0x01對(duì)應(yīng)線圈操作,0x02對(duì)應(yīng)離散量操作,0x03對(duì)應(yīng)保持寄存器操作,0x04對(duì)應(yīng)輸入寄存器操作
            – address:開始地址
            – quantity:寄存器/線圈/離散量 的數(shù)量


          一些概念

          在工業(yè)自動(dòng)化控制中,經(jīng)常會(huì)遇到開關(guān)量,數(shù)字量,模擬量,離散量,脈沖量等各種概念,而人們?cè)趯?shí)際應(yīng)用中,對(duì)于這些概念又很容易混淆。現(xiàn)將各種概念羅列如下:

          1.開關(guān)量:

          一般指的是觸點(diǎn)的“開”與“關(guān)”的狀態(tài),一般在計(jì)算機(jī)設(shè)備中也會(huì)用“0”或“1”來(lái)表示開關(guān)量的狀態(tài)。開關(guān)量分為有源開關(guān)量信號(hào)和無(wú)源開關(guān)量信號(hào),有源開關(guān)量信號(hào)指的是“開”與“關(guān)”的狀態(tài)是帶電源的信號(hào),專業(yè)叫法為躍階信號(hào),可以理解為脈沖量,一般的都有220VAC,?110VAC,24VDC,12VDC等信號(hào),無(wú)源開關(guān)量信號(hào)指的是“開”和“關(guān)”的狀態(tài)時(shí)不帶電源的信號(hào),一般又稱之為干接點(diǎn)。電阻測(cè)試法為電阻0或無(wú)窮大。

          2.數(shù)字量:

          很多人會(huì)將數(shù)字量與開關(guān)量混淆,也將其與模擬量混淆。數(shù)字量在時(shí)間和數(shù)量上都是離散的物理量,其表示的信號(hào)則為數(shù)字信號(hào)。數(shù)字量是由0和1組成的信號(hào),經(jīng)過(guò)編碼形成有規(guī)律的信號(hào),量化后的模擬量就是數(shù)字量。

          3.模擬量:

          模擬量的概念與數(shù)字量相對(duì)應(yīng),但是經(jīng)過(guò)量化之后又可以轉(zhuǎn)化為數(shù)字量。模擬量是在時(shí)間和數(shù)量上都是連續(xù)的物理量,其表示的信號(hào)則為模擬信號(hào)。模擬量在連續(xù)的變化過(guò)程中任何一個(gè)取值都是一個(gè)具體有意義的物理量,如溫度,電壓,電流等。

          4.離散量:

          離散量是將模擬量離散化之后得到的物理量。即任何儀器設(shè)備對(duì)于模擬量都不可能有個(gè)完全精確的表示,因?yàn)樗麄兌加幸粋€(gè)采樣周期,在該采樣周期內(nèi),其物理量的數(shù)值都是不變的,而實(shí)際上的模擬量則是變化的。這樣就將模擬量離散化,成為了離散量。

          5.脈沖量:

          脈沖量就是瞬間電壓或電流由某一值躍變到另一值的信號(hào)量。在量化后,其變化持續(xù)有規(guī)律就是數(shù)字量,如果其由0變成某一固定值并保持不變,其就是開關(guān)量。

          綜上所述,模擬量就是在某個(gè)過(guò)程中時(shí)間和數(shù)量連續(xù)變化的物理量,由于在實(shí)際的應(yīng)用中,所有的儀器設(shè)備對(duì)于外界數(shù)據(jù)的采集都有一個(gè)采樣周期,其采集的數(shù)據(jù)只有在下一個(gè)采樣周期開始時(shí)才有變動(dòng),采樣周期內(nèi)其數(shù)值并不隨模擬量的變化而變動(dòng)。

          這樣就將模擬量離散化了,例如:某設(shè)備的采樣周期為1秒,其在第五秒的時(shí)間采集的溫度為35度,而第六秒的溫度為36度,該設(shè)備就只能標(biāo)稱第五秒時(shí)間溫度35度,第六秒時(shí)間溫度36度,而第五點(diǎn)五秒的時(shí)間其標(biāo)稱也只是35度,但是其實(shí)際的模擬量是35.5度。這樣就將模擬信號(hào)離散化。其采集的數(shù)據(jù)就是離散化了,不再是連續(xù)的模擬量信號(hào)。

          由于計(jì)算機(jī)只識(shí)別0和1兩個(gè)信號(hào),即開關(guān)量信號(hào),用其來(lái)表示數(shù)值都是使用數(shù)字串來(lái)表示,由于計(jì)算能力的問(wèn)題,其數(shù)字串不能無(wú)限長(zhǎng),即其表達(dá)的精度也是有限的,同樣的以溫度為例,由于數(shù)字串限制,其表達(dá)溫度的精度只能達(dá)到0.1度,小于該單位的數(shù)值則不能被標(biāo)稱,這樣就必須將離散量進(jìn)行量化,將其變?yōu)閿?shù)字量。即35.68度的溫度則表示為35.6度。

          免責(zé)聲明:本文轉(zhuǎn)自網(wǎng)絡(luò),版權(quán)歸原作者所有,如涉及作品版權(quán)問(wèn)題,請(qǐng)及時(shí)與我們聯(lián)系刪除,謝謝!

          16款電工仿真軟件


          者公眾號(hào):org_yijiaoqian

          從一個(gè)HTTP請(qǐng)求來(lái)看網(wǎng)絡(luò)分層原理


          兩臺(tái)主機(jī)間會(huì)通過(guò)非常多網(wǎng)絡(luò)設(shè)備,不管哪個(gè)網(wǎng)絡(luò)設(shè)備都會(huì)發(fā)生數(shù)據(jù)丟失,如果發(fā)生數(shù)據(jù)丟失的話,會(huì)發(fā)生數(shù)據(jù)重傳,會(huì)出現(xiàn)數(shù)據(jù)重復(fù)(之前丟失的包并不是丟失而是產(chǎn)生了延時(shí))。數(shù)據(jù)傳輸?shù)慕橘|(zhì)也可能多樣,如內(nèi)網(wǎng)里通過(guò)網(wǎng)線進(jìn)行傳輸,連接到公網(wǎng)的話會(huì)通過(guò)光纖進(jìn)行連接,所以要實(shí)現(xiàn)不同介質(zhì)間信號(hào)的轉(zhuǎn)換,還有從光纖到路由器無(wú)線脈沖轉(zhuǎn)換,距離遠(yuǎn)的話還有信號(hào)衰減問(wèn)題。所以在網(wǎng)絡(luò)傳輸過(guò)程中有非常多的問(wèn)題需要解決,把問(wèn)題分組分層,不同層次間解決不同問(wèn)題,不同層次間定義標(biāo)準(zhǔn)化接口讓它們間可以進(jìn)行數(shù)據(jù)的通信。


          復(fù)雜的網(wǎng)絡(luò)

          為了簡(jiǎn)化網(wǎng)絡(luò)的復(fù)雜度,網(wǎng)絡(luò)通信的不同方面被分解為多層次結(jié)構(gòu),每一層只與緊挨著的上層或者下層進(jìn)行交互,將網(wǎng)絡(luò)分層,這樣就可以修改,甚至替換某一層的軟件,只要層與層之間的接口保持不變,就不會(huì)影響到其他層。

            • OSI( Open System Interconnection Reference Model): 開放系統(tǒng)互聯(lián)參考模型
            • TCP/IP 協(xié)議族


          OSI七層理論體系結(jié)構(gòu)

          1. 物理層:解決兩臺(tái)主機(jī)的通信問(wèn)題—A往B發(fā)送比特流(0101),B能接收到這些比特流。定義了物理設(shè)備的標(biāo)準(zhǔn)如網(wǎng)線的類型,光纖的接口類型以及傳輸介質(zhì)的傳輸速率等。
          2. 數(shù)據(jù)鏈路層:由于物理層上的傳輸?shù)谋忍亓骺赡軙?huì)出現(xiàn)錯(cuò)傳、誤傳等,所以數(shù)據(jù)鏈路層定義了如何格式化數(shù)據(jù)即將比特流封裝成,提供了錯(cuò)誤檢測(cè)。
          3. 網(wǎng)絡(luò)層:隨著節(jié)點(diǎn)的增加,點(diǎn)對(duì)點(diǎn)通信是需要經(jīng)過(guò)多個(gè)節(jié)點(diǎn)的,如何找到目標(biāo)節(jié)點(diǎn),如何找到最優(yōu)路徑變成為了首要需求。所以出現(xiàn)了網(wǎng)絡(luò)層,主要目的是將網(wǎng)絡(luò)地址翻譯成對(duì)應(yīng)的物理地址,分組傳輸、路由選擇,本層的傳輸單位是數(shù)據(jù)報(bào)(分組),本層需要注意的TCP/IP協(xié)議中的TCP協(xié)議。
          4. 傳輸層:隨著網(wǎng)絡(luò)需要的進(jìn)一步擴(kuò)大,通信過(guò)程中需要傳輸大量的數(shù)據(jù),網(wǎng)絡(luò)可能會(huì)發(fā)生中斷,為了保證傳輸大量文件時(shí)的準(zhǔn)確性,需要對(duì)發(fā)送的數(shù)據(jù)進(jìn)行切分,切分成一個(gè)個(gè)的segment進(jìn)行發(fā)送,考慮如何在接受方拼接切分的segment組成完整的數(shù)據(jù),以及發(fā)現(xiàn)丟失segment時(shí)該如何處理,需要注意的協(xié)議TCP、UDP。
          5. 會(huì)話層:不同機(jī)器上的用戶之間建立以及管理會(huì)話。用于保證應(yīng)用程序自動(dòng)收發(fā)包和尋址。
          6. 表示層:信息的語(yǔ)義語(yǔ)法,加密解密,轉(zhuǎn)換翻譯,壓縮解壓縮。
          7. 應(yīng)用層:規(guī)定雙方必須使用固定長(zhǎng)度的消息頭,且消息頭必須記錄消息長(zhǎng)度等信息。需要注意的是TCP/IP協(xié)議中的HTTP協(xié)議。


          TCP/IP四層模型


          是OSI的一種實(shí)現(xiàn),包括應(yīng)用層、運(yùn)輸層、網(wǎng)際層和網(wǎng)絡(luò)接口層。



          一個(gè)HTTP請(qǐng)求的分層解析流程

          如上圖右邊一個(gè)服務(wù)器部署了一個(gè)靜態(tài)頁(yè)面,通過(guò)nginx部署在公網(wǎng)上,瀏覽器通過(guò)域名對(duì)它進(jìn)行訪問(wèn),瀏覽器輸入域名點(diǎn)回車后是怎么工作的呢?

          http://www.dumain.com

          服務(wù)端只認(rèn)ip地址,瀏覽器將域名解析出來(lái),看下瀏覽器里有沒有域名對(duì)應(yīng)DNS的緩存,有的話直接拿到服務(wù)端的ip地址,沒有的話去本地的host文件看有沒有配置,沒有配置的話才會(huì)發(fā)起一個(gè)DNS請(qǐng)求用來(lái)獲取服務(wù)器ip地址。


          DNS也是臺(tái)服務(wù)器也有自己的ip地址,這時(shí)候應(yīng)用層會(huì)構(gòu)造一個(gè)DNS請(qǐng)求報(bào)文,應(yīng)用層會(huì)去調(diào)用傳輸層的接口一個(gè)socket的API,DNS默認(rèn)使用UDP實(shí)現(xiàn)數(shù)據(jù)傳輸,即應(yīng)用層調(diào)用傳輸層的API,傳輸層會(huì)在DNS請(qǐng)求報(bào)文基礎(chǔ)上加一個(gè)UDP的請(qǐng)求頭,傳輸層將數(shù)據(jù)交給網(wǎng)絡(luò)層,網(wǎng)絡(luò)層同樣在UDP請(qǐng)求報(bào)文基礎(chǔ)上加IP的請(qǐng)求頭,網(wǎng)絡(luò)層會(huì)將IP請(qǐng)求報(bào)文交給數(shù)據(jù)鏈路層,數(shù)據(jù)鏈路層會(huì)將自己的mac頭加上去并把對(duì)應(yīng)的請(qǐng)求報(bào)文交給下一個(gè)機(jī)器的mac地址也會(huì)加上去,下一個(gè)機(jī)器的mac地址通過(guò)網(wǎng)絡(luò)層ARP協(xié)議找到,ARP會(huì)發(fā)送一些請(qǐng)求看下你對(duì)應(yīng)的ip地址的mac地址是多少,最后通過(guò)物理層物理介質(zhì)傳出去,通常傳到路由器上.


          路由器是三層設(shè)備(從下向上)從物理層開始連接,物理層交給數(shù)據(jù)鏈路層,數(shù)據(jù)鏈路層看下地址是不是給我的,是給我的進(jìn)行解析,不是給我的就丟棄,報(bào)文再傳給上面一層網(wǎng)絡(luò)層,網(wǎng)絡(luò)層把數(shù)據(jù)傳到下一個(gè)路由器的地址是多少,會(huì)通過(guò)運(yùn)營(yíng)商的網(wǎng)絡(luò)接口傳到運(yùn)營(yíng)商的路由器上,運(yùn)營(yíng)商有自己的DNS服務(wù)器,如果配置的是運(yùn)營(yíng)商自己的DNS服務(wù)器的話會(huì)直接在這個(gè)DNS服務(wù)器里找自己對(duì)應(yīng)的域名拿到對(duì)應(yīng)的ip地址,也就是剛請(qǐng)求DNS報(bào)文地址,然后原路返回解析直到應(yīng)用層拿到剛域名對(duì)應(yīng)的ip地址,這樣就可以進(jìn)行HTTP請(qǐng)求報(bào)文的發(fā)送,再調(diào)用傳輸層協(xié)議是TCP參數(shù),同樣每到一層加頭。


          HTTP

          什么是HTTP?

          超文本傳輸協(xié)議,是一個(gè)基于請(qǐng)求與響應(yīng),無(wú)狀態(tài)的,應(yīng)用層的協(xié)議,常基于TCP/IP協(xié)議傳輸數(shù)據(jù),互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議,所有的WWW文件都必須遵守這個(gè)標(biāo)準(zhǔn)。設(shè)計(jì)HTTP的初衷是為了提供一種發(fā)布和接收HTML頁(yè)面的方法。


          HTTP特點(diǎn)

          1. 無(wú)狀態(tài):協(xié)議對(duì)客戶端沒有狀態(tài)存儲(chǔ),對(duì)事物處理沒有“記憶”能力,比如訪問(wèn)一個(gè)網(wǎng)站需要反復(fù)進(jìn)行登錄操作。
          2. 無(wú)連接:HTTP/1.1之前,由于無(wú)狀態(tài)特點(diǎn),每次請(qǐng)求需要通過(guò)TCP三次握手四次揮手,和服務(wù)器重新建立連接。比如某個(gè)客戶機(jī)在短時(shí)間多次請(qǐng)求同一個(gè)資源,服務(wù)器并不能區(qū)別是否已經(jīng)響應(yīng)過(guò)用戶的請(qǐng)求,所以每次需要重新響應(yīng)請(qǐng)求,需要耗費(fèi)不必要的時(shí)間和流量。
          3. 基于請(qǐng)求和響應(yīng):基本的特性,由客戶端發(fā)起請(qǐng)求,服務(wù)端響應(yīng)。
          4. 簡(jiǎn)單快速、靈活。
          5. 通信使用明文、請(qǐng)求和響應(yīng)不會(huì)對(duì)通信方進(jìn)行確認(rèn)、無(wú)法保護(hù)數(shù)據(jù)的完整性。


          HTTP協(xié)議版本已經(jīng)演化到3.0版本,關(guān)于協(xié)議版本可以查看 快速掌握HTTP1.0 1.1 2.0 3.0的特點(diǎn)及其區(qū)別


          HTTP報(bào)文格式


          HTTP 協(xié)議的請(qǐng)求報(bào)文和響應(yīng)報(bào)文的結(jié)構(gòu)基本相同,由三大部分組成:

          • 起始行(start line):描述請(qǐng)求或響應(yīng)的基本信息
          • 頭部字段集合(header):使用 key-value 形式更詳細(xì)地說(shuō)明報(bào)文
          • 消息正文(entity):實(shí)際傳輸?shù)臄?shù)據(jù),它不一定是純文本,可以是圖片、視頻等二進(jìn)制數(shù)據(jù)


          其中起始行和頭部的字段并成為 請(qǐng)求頭 或者 響應(yīng)頭,統(tǒng)稱為 Header;消息正文也叫實(shí)體,稱為 body。HTTP 協(xié)議規(guī)定每次發(fā)送的報(bào)文必須要有 Header,但是可以沒有 body,也就是說(shuō)頭信息是必須的,實(shí)體信息可以沒有。而且在 header 和 body 之間必須要有一個(gè)空行(CRLF)。

          請(qǐng)求行報(bào)文格式

          • 請(qǐng)求方法:如 GET/HEAD/PUT/POST,表示對(duì)資源的操作;
          • 請(qǐng)求目標(biāo):通常是一個(gè) URI,標(biāo)記了請(qǐng)求方法要操作的資源;
          • 版本號(hào):表示報(bào)文使用的 HTTP 協(xié)議版本。


          響應(yīng)報(bào)文格式

          • 版本號(hào):表示報(bào)文使用的 HTTP 協(xié)議版本;
          • 狀態(tài)碼:一個(gè)三位數(shù),用代碼的形式表示處理的結(jié)果,比如 200 是成功,500 是服務(wù)器錯(cuò)誤;
          • 原因:作為數(shù)字狀態(tài)碼補(bǔ)充,是更詳細(xì)的解釋文字,幫助人理解原因。


          請(qǐng)求及響應(yīng)報(bào)文格式對(duì)比


          HTTP 頭字段


          頭部字段是 key-value 的形式,key 和 value 之間用“:”分隔,最后用 CRLF 換行表示字

          段結(jié)束。比如前后分離時(shí)經(jīng)常遇到的要與后端協(xié)商傳輸數(shù)據(jù)的類型“Content-type: application/json”,這里 key 就是“Content-type”,value 就 是“application/json”。HTTP 頭字段非常靈活,不僅可以使用標(biāo)準(zhǔn)里的 Host、 Connection 等已有頭,也可以任意添加自定義頭,這就給 HTTP 協(xié)議帶來(lái)了無(wú)限的擴(kuò)展可能。


          頭字段注意事項(xiàng)

          • 字段名不區(qū)分大小寫,字段名里不允許出現(xiàn)空格,可以使用連字符“-”,但不
          • 能使用下劃線“_”(有的服務(wù)器不會(huì)解析帶“_”的頭字段)。字段名后面必須緊接 著“:”,不能有空格,而“:”后的字段值前可以有多個(gè)空格;
          • 字段的順序是沒有意義的,可以任意排列不影響語(yǔ)義;
          • 字段原則上不能重復(fù),除非這個(gè)字段本身的語(yǔ)義允許,例如 Set-Cookie。

          HTTP 協(xié)議中有非常多的頭字段,但基本上可以分為四大類:通用標(biāo)頭實(shí)體標(biāo)頭請(qǐng)求標(biāo)頭響應(yīng)標(biāo)頭

          HTTP 頭字段更多內(nèi)容請(qǐng)查看《深入掌握HTTP四種標(biāo)頭基本概念 》


          TCP 協(xié)議


          TCP(Transmission Control Protocol),傳輸控制協(xié)議:面向連接的,可靠的,基于字節(jié)流的傳輸層通信協(xié)議。它能幫助你確定計(jì)算機(jī)連接到 Internet 以及它們之間的數(shù)據(jù)傳輸。通過(guò)三次握手來(lái)建立 TCP 連接,三次握手就是用來(lái)啟動(dòng)和確認(rèn) TCP 連接的過(guò)程。一旦連接建立后,就可以發(fā)送數(shù)據(jù)了,當(dāng)數(shù)據(jù)傳輸完成后,會(huì)通過(guò)關(guān)閉虛擬電路來(lái)斷開連接。


          TCP特點(diǎn)


          • 基于連接的:數(shù)據(jù)傳輸之前需要建立連接
            全雙工的:雙向傳輸
          • 字節(jié)流:不限制數(shù)據(jù)大小,打包成報(bào)文段,保證有序接收,重復(fù)報(bào)文自動(dòng)丟棄
          • 流量緩沖:解決雙方處理能力的不匹配
          • 可靠的傳輸服務(wù):保證可達(dá),丟包時(shí)通過(guò)重發(fā)機(jī)制實(shí)現(xiàn)可靠性
          • 擁塞控制:防止網(wǎng)絡(luò)出現(xiàn)惡性擁塞


          TCP報(bào)文格式



          • 16位源端口/16位目的端口:負(fù)責(zé)實(shí)現(xiàn)應(yīng)用程序之間的數(shù)據(jù)傳輸
          • 32位序號(hào)/32位確認(rèn)序號(hào):用于實(shí)現(xiàn)tcp在傳輸層的包序管理——tcp有序交付數(shù)據(jù)
          • 4位頭部長(zhǎng)度:以4個(gè)字節(jié)為單位;4位保存的最大數(shù)字是15;因此tcp報(bào)頭最大長(zhǎng)度是15*4=60個(gè)字節(jié)
          • 6位保留位
          • 6位標(biāo)志
            • URG——緊急指針標(biāo)志
            • ACK——確認(rèn)回復(fù)標(biāo)志
            • PSH——提示立即接受位
            • RST——重置連接位
            • SYN——連接建立請(qǐng)求位
            • FIN——斷開連接請(qǐng)求位
          • 16位窗口大小:滑動(dòng)窗口機(jī)制–>流量控制–>告訴對(duì)端所能發(fā)送的最大數(shù)據(jù)量
          • 校驗(yàn)和:二進(jìn)制反碼求和–>校驗(yàn)數(shù)據(jù)一致性
          • 緊急指針:指明哪些數(shù)據(jù)是緊急數(shù)據(jù)
          • 選項(xiàng)數(shù)據(jù):三次握手時(shí),協(xié)商MSS大小的數(shù)據(jù)


          TCP連接:四元組[ 源地址, 源端口, 目的地址, 目的端口 ]


          TCP三次握手


          • 同步通信雙方初始序列號(hào)( ISN, initial sequence number )
          • 協(xié)商TCP通信參數(shù)(MSS, 窗口信息,指定校驗(yàn)和算法)


          在了解具體流程之前,我們先認(rèn)識(shí)幾個(gè)概念


          最初兩端的TCP進(jìn)程都處于CLOSED關(guān)閉狀態(tài),A主動(dòng)打開連接,而B被動(dòng)打開連接。

          A、B關(guān)閉狀態(tài)CLOSED — B收聽狀態(tài)LISTEN — A同步已發(fā)送狀態(tài)SYN-SENT — B同步收到狀態(tài)SYN-RCVD— A、B連接已建立狀態(tài)ESTABLISHED

          B的TCP服務(wù)器進(jìn)程先創(chuàng)建傳輸控制塊TCB,準(zhǔn)備接受客戶進(jìn)程的連接請(qǐng)求。然后服務(wù)器進(jìn)程就處于LISTEN(收聽)狀態(tài),等待客戶的連接請(qǐng)求。若有,則作出響應(yīng)。


          • SYN:它的全稱是 Synchronize Sequence Numbers ,同步序列編號(hào)。是 TCP/IP 建立連接時(shí)使用的握手信號(hào)。在客戶機(jī)和服務(wù)器之間建立 TCP 連接時(shí),首先會(huì)發(fā)送的一個(gè)信號(hào)。客戶端在發(fā)送 SYN 消息時(shí),就會(huì)在自己的段內(nèi)生成一個(gè)隨機(jī)值 X
          • SYN-ACK:服務(wù)器收到 SYN 后,應(yīng)答客戶端連接,發(fā)送一個(gè) SYN-ACK作為答復(fù)。確認(rèn)號(hào)設(shè)置為比接收到的序列號(hào)多一個(gè),即 X + 1,服務(wù)器為數(shù)據(jù)包選擇的序列號(hào)是另一個(gè)隨機(jī)數(shù) Y
          • ACK: Ackowledge character ,確認(rèn)字符,表示發(fā)來(lái)的數(shù)據(jù)已確認(rèn)接收無(wú)誤。最后客戶端將 ACK 發(fā)送給服務(wù)器。序列號(hào)被設(shè)置為所接收的確認(rèn)值即 Y+ 1


          下面通過(guò)一個(gè)案例看三次握手是怎么進(jìn)行的

          • 在Nginx服務(wù)器部署一個(gè)靜態(tài)頁(yè)面(我的端口為:8000)

          • tcpdump指定網(wǎng)卡進(jìn)行監(jiān)聽抓取報(bào)文
          tcpdump -i en0 -S -c 3 port 8000
          • 在客戶端使用nc網(wǎng)絡(luò)工具發(fā)送一個(gè)請(qǐng)求
          nc 192.168.109.200 8000
          • 三次握手監(jiān)聽結(jié)果如下:


          • 內(nèi)核在三次握手做的一些事情,如下:

          • 連接狀態(tài)查看
          netstat -tpn # t:TCP連接裝,p:進(jìn)程顯示 ,n:數(shù)字形式
          # 每秒查看一次
          netstat -tpn -c 1


          TCP四次揮手


          • A: 發(fā)送FIN數(shù)據(jù)包,代表A不再發(fā)送數(shù)據(jù)
          • B: 收到請(qǐng)求,開始應(yīng)答 ,避免了A重新發(fā)送FIN重試(應(yīng)答機(jī)制)
          • B: 處理完數(shù)據(jù)之后關(guān)閉,關(guān)閉連接,及發(fā)送FIN請(qǐng)求
          • A: 收到請(qǐng)求后發(fā)送ACK應(yīng)答,B服務(wù)可以釋放連接


          等待 2MSL后釋放連接

          1. 防止報(bào)文丟失,導(dǎo)致B重復(fù)發(fā)送FIN
          2. 防止滯留在網(wǎng)絡(luò)中的報(bào)文,對(duì)新建立的連接造成數(shù)據(jù)擾亂


          字節(jié)流的協(xié)議


          TCP把應(yīng)用交付的數(shù)據(jù)僅僅看成是一連串的無(wú)結(jié)構(gòu)的字節(jié)流,TCP并不 知道字節(jié)流的含義,TCP并不關(guān)心應(yīng)用程序一次將多大的報(bào)文發(fā)送到 TCP的緩存中,而是根據(jù)對(duì)方給出的窗口值和當(dāng)前網(wǎng)絡(luò)擁堵的程度來(lái)決 定一個(gè)報(bào)文段應(yīng)該包含多少個(gè)字節(jié)。

          MSS: Max Segment Size, 默認(rèn) 536byte 實(shí)際數(shù)據(jù)

          在網(wǎng)絡(luò)傳輸過(guò)程中可能會(huì)出現(xiàn)以下的一些情況:

          • 客戶端一段時(shí)間沒有收到 ack 消息則重傳
          • 如果緩沖區(qū)滿了則可能丟包或延時(shí)都需要重傳
          • 根據(jù)報(bào)文 sequeence number 字段重排序,還需要丟棄重復(fù)包。


          數(shù)據(jù)傳輸?shù)目煽啃?/h1>


          停止等待協(xié)議如下:

          停止等待協(xié)議,效率比較低


          重傳機(jī)制如下:

          • ack 報(bào)文丟失

          • 請(qǐng)求報(bào)文丟失


          滑動(dòng)窗口協(xié)議與累計(jì)確認(rèn)(延時(shí)ack)

          如上效率低,所以tcp提出了新的協(xié)議-滑動(dòng)窗口協(xié)議與累計(jì)確認(rèn)(延時(shí)ack)。

          滑動(dòng)窗口大小同通過(guò)tcp三次握手和對(duì)端協(xié)商,且受網(wǎng)絡(luò)狀況影響。

          上面是一個(gè)一個(gè)報(bào)文,實(shí)際可發(fā)一批報(bào)文,服務(wù)器并不是挨個(gè)去確認(rèn),上面回一個(gè)ack浪費(fèi)資源,單獨(dú)響應(yīng)一個(gè)報(bào)文時(shí),tcp本身一個(gè)報(bào)文至少20個(gè)字節(jié)再加上ip頭報(bào)文20字節(jié),所以一個(gè)ack至少40字節(jié)。

          所以延時(shí)ack的發(fā)送,如下圖確認(rèn)最后一個(gè)報(bào)文如5就可以,但這樣也有一個(gè)問(wèn)題如3的報(bào)文丟了,這時(shí)只能確認(rèn)1和2連續(xù)報(bào)文,從3以后的報(bào)文全要重傳,已確認(rèn)的報(bào)文在緩沖區(qū)丟棄掉。


          文章持續(xù)更新,可以公眾號(hào)搜一搜「 一角錢技術(shù) 」第一時(shí)間閱讀, 本文 GitHub org_hejianhui/JavaStudy 已經(jīng)收錄,歡迎 Star。


          主站蜘蛛池模板: 日韩社区一区二区三区| 日韩精品一区在线| 日本欧洲视频一区| 国产视频一区二区在线播放| 亚洲AV无码一区二区一二区| 精品人妻无码一区二区三区蜜桃一 | 亚洲AV日韩综合一区| 成人免费区一区二区三区| 手机看片一区二区| 少妇人妻精品一区二区三区| 国模私拍福利一区二区| 精品国产一区二区三区在线| 立川理惠在线播放一区| 国产日韩精品一区二区三区在线| 国产激情无码一区二区| 亚洲a∨无码一区二区| 免费在线观看一区| 色婷婷综合久久久久中文一区二区| 熟妇人妻AV无码一区二区三区| 国产91久久精品一区二区| 国产成人无码aa精品一区| 伊人久久精品一区二区三区| 中文字幕无码不卡一区二区三区| 熟女大屁股白浆一区二区| 亚欧在线精品免费观看一区| 亚洲AV日韩综合一区尤物| 国产成人久久一区二区不卡三区 | 国产一区高清视频| 波多野结衣高清一区二区三区| 亚洲狠狠久久综合一区77777| 中文字幕乱码人妻一区二区三区| 精品人妻一区二区三区四区| 午夜精品一区二区三区免费视频| 在线免费一区二区| 国产高清不卡一区二区| 日本福利一区二区| 无码精品人妻一区二区三区人妻斩| 在线观看国产一区二区三区| 无码一区二区三区视频| 亚洲AⅤ无码一区二区三区在线 | 丰满人妻一区二区三区免费视频 |