欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺析NIO系列之TCP

 更新時(shí)間:2021年06月15日 09:31:37   作者:wier  
NIO即同步非阻塞式IO,它和傳統(tǒng)的BIO比較最大的區(qū)別在于在執(zhí)行accept、connect、read、write操作時(shí)是非阻塞的。很有利于實(shí)現(xiàn)用少量線(xiàn)程來(lái)處理多個(gè)客戶(hù)端請(qǐng)求,可以隨時(shí)讓線(xiàn)程切換所處理的客戶(hù)端,從而可以實(shí)現(xiàn)高并發(fā)服務(wù)器的開(kāi)發(fā)

一、前言

在spring boot 2中,默認(rèn)的web 容器是netty ,這說(shuō)明“反應(yīng)式” 容器已經(jīng)是大勢(shì)所趨,無(wú)論是go 語(yǔ)言的協(xié)從線(xiàn)程,還是java 基于reactor 線(xiàn)程模型,都是基于事件編程實(shí)現(xiàn)高并發(fā)的實(shí)例。

在介紹NIO之前有必要了解下TCP協(xié)議,因?yàn)槟壳岸鄶?shù)應(yīng)用都是給予應(yīng)用層進(jìn)行操作,導(dǎo)致隱藏了大量的網(wǎng)路細(xì)節(jié),知道這些細(xì)節(jié)以及原理對(duì)我們的問(wèn)題排查很有益處。

二、TCP 特性

TCP 是一種面向連接的協(xié)議,它給用戶(hù)進(jìn)程提供可靠的全雙工的字節(jié)流。確保數(shù)據(jù)包的可靠,有序,以及支持流量控制。關(guān)于TCP 為何要做這些,我們從以下幾個(gè)方面入手:

1.IP網(wǎng)絡(luò)層為何不保證數(shù)據(jù)包的可靠性

2.TCP協(xié)議如何保證包可達(dá)、有序

3.TCP協(xié)議如何支持流量控制

4.TCP幾種狀態(tài)以及應(yīng)用

三、IP網(wǎng)絡(luò)層為何不保證數(shù)據(jù)包的可靠性

我們先看下OSI的網(wǎng)絡(luò)分層,在以下分層中,TCP 位于傳輸層,它保證的是協(xié)議的可靠性和連續(xù)性。具體的收發(fā)報(bào)是有底層的鏈路層以及物理層所決定的,所以TCP 所做的工作,也是基于底層的優(yōu)化和改進(jìn)。

客戶(hù)端與服務(wù)器之間的通信使用應(yīng)用協(xié)議,傳輸層的通信采用TCP協(xié)議,而TCP 協(xié)議又采用了更低的一層IP協(xié)議,IP則使用某種形式的數(shù)據(jù)鏈路層通信。

我們知道網(wǎng)絡(luò)的中的數(shù)據(jù),最終通過(guò)多個(gè)路由器連接傳送的。最底層的以太網(wǎng)協(xié)議規(guī)定了電子信號(hào)如何組成數(shù)據(jù)包,解決了局域網(wǎng)的點(diǎn)對(duì)點(diǎn)通信問(wèn)題,但無(wú)法解決多個(gè)局域網(wǎng)的的互通問(wèn)題。

而網(wǎng)絡(luò)層采用的IP協(xié)議,就是定義了一套自己的地址規(guī)則,主要解決尋址和路由的功能,根據(jù)對(duì)方的IP地址,尋找最佳路徑傳輸信息。局域網(wǎng)通過(guò)路由器連接,路由器基于IP協(xié)議,指導(dǎo)數(shù)據(jù)包向某個(gè)路由借口轉(zhuǎn)發(fā)。但I(xiàn)P協(xié)議不保證包一定到達(dá)以及完整性,特別是網(wǎng)絡(luò)擁堵的時(shí)候,會(huì)丟棄一些數(shù)據(jù)包,保證數(shù)據(jù)的傳送效率。

而保證數(shù)據(jù)包的完整、有序以及可靠,這就是TCP 協(xié)議要來(lái)做的事情了。

四、TCP 協(xié)議

4.1、TCP 包組成

很多網(wǎng)絡(luò)有一個(gè)最大傳送單元,它是鏈路層中的網(wǎng)絡(luò)對(duì)數(shù)據(jù)幀的一個(gè)限制,以以太網(wǎng)為例,MTU為1500個(gè)字節(jié)。一個(gè)IP數(shù)據(jù)報(bào)在以太網(wǎng)中 傳輸,如果它的長(zhǎng)度大于該MTU值,就要進(jìn)行分片傳輸,使得每片數(shù)據(jù)報(bào)的長(zhǎng)度小于MTU。

另外一個(gè)數(shù)據(jù)包還包含頭信息,除了自己的Tcp包頭,還有IP 頭信息和以太網(wǎng)頭信息。IP 數(shù)據(jù)包在以太網(wǎng)數(shù)據(jù)包的負(fù)載里面,最少需要20字節(jié),所以 IP 數(shù)據(jù)包的負(fù)載最多為1480字節(jié)。

那么tcp的一個(gè)包大小是多少吶?

我們需要機(jī)遇MSS這個(gè)值來(lái)確定,MSS是TCP里的一個(gè)概念(首部的選項(xiàng)字段中)。MSS是TCP數(shù)據(jù)包每次能夠傳輸?shù)淖畲髷?shù)據(jù)分段,TCP報(bào)文段的長(zhǎng)度大于MSS時(shí),要進(jìn)行分段傳輸。 如果不設(shè)置,則MSS的默認(rèn)值就為536個(gè)字節(jié) 。也就是說(shuō)一個(gè)tcp包的在500字節(jié)左右。

4.2、如何保證可靠性

上述也說(shuō)了,底層的路由轉(zhuǎn)發(fā)包,并不保證包的可靠性以及有序性。

首先為了保證包的完整性,TCP 會(huì)基于MSS 為大于 MSS的包進(jìn)行分包處理,默認(rèn)MSS大小為563byte,其大小小于MUT,以防止在網(wǎng)絡(luò)層被分片處理。

其次增加SEQ和ACK,同時(shí)采用超時(shí)重發(fā)的機(jī)制來(lái)保證包的可靠性。

1)SEQ

為了保證有序性,TCP 為每個(gè)包編配一個(gè)Sequence number ,簡(jiǎn)稱(chēng) SEQ 。以便接收的一方按照順序還原。萬(wàn)一發(fā)生丟包,也可以知道丟失的是哪一個(gè)包。一般第一個(gè)包的編號(hào)是一個(gè)隨機(jī)數(shù),也可以從1開(kāi)始。

2)ACK

那么有編號(hào)了,如何確保包一定到達(dá)?

基于ACK 進(jìn)行確認(rèn)。對(duì)于接收方來(lái)說(shuō),每次接受一個(gè)包必須返回ack信息,發(fā)送端從而確認(rèn)這個(gè)包已經(jīng)傳送到。另外,接收方要對(duì)每一條報(bào)文做校驗(yàn)。如果校驗(yàn)發(fā)現(xiàn)出錯(cuò),則不發(fā)送確認(rèn)報(bào)文,從而觸發(fā)發(fā)送方超時(shí)重傳。

ACK 包含以下信息:

  • 期待要收到下一個(gè)數(shù)據(jù)包的編號(hào) next SEQ
  • 接收方的接收窗口的剩余容量

我們采用wiershark抓包一個(gè)oschina的包看下三次握手的數(shù)據(jù)。

我的本機(jī)ip:192.168.1.103

oschinaIp:116.211.174.177

三次握手過(guò)程:

1.me->osChina:syn=1 seq=x ack=0

2.osChina->me:syn=1 seq=y ack=x+1

3.me->osChina:seq=x+1 ack=y+1


1、me->osChina:syn=1 seq=0 ack=0

2、osChina->me:syn=1 seq=0 ack=0+1

3、me->osChina:seq=0+1 ack=0+1

對(duì)比一下三次握手的過(guò)程。

3)超時(shí)重傳

我們知道網(wǎng)絡(luò)極其不穩(wěn)定,數(shù)據(jù)包即便增加了SEQ和ACK,能夠保證其有序性,但依然保證丟包或者超時(shí)的問(wèn)題。如果發(fā)送端發(fā)送數(shù)據(jù),或者接收端回復(fù)ACK的消息在網(wǎng)絡(luò)中丟失或者超時(shí)怎么處理?

RTO ,超時(shí)重傳時(shí)間。要知道包是否出現(xiàn)超時(shí),需要有一個(gè)評(píng)估方式,而RTT是對(duì)一個(gè)給定連接的往返時(shí)間的測(cè)量。由于網(wǎng)絡(luò)流量的變化,這個(gè)時(shí)間會(huì)相應(yīng)地發(fā)生改變,TCP需要跟蹤這些變化并動(dòng)態(tài)調(diào)整超時(shí)時(shí)間RTO。

發(fā)送方如果一定時(shí)間內(nèi)沒(méi)收到報(bào)文的ACK,就認(rèn)為該報(bào)文丟失在網(wǎng)絡(luò)中了,自動(dòng)重發(fā)該報(bào)文。這種機(jī)制稱(chēng)之為超時(shí)重傳。

在這期間,如果接收端的消息,由于丟失,接收端沒(méi)有收到ack 消息,發(fā)送端會(huì)向接收端重發(fā)這個(gè)包。如果因?yàn)槌瑫r(shí)原因,發(fā)送端在超時(shí)定時(shí)器之后收到了這個(gè)包的ack 信息,而且發(fā)送端已經(jīng)重復(fù)發(fā)送了這個(gè)消息,此時(shí)發(fā)送端不會(huì)處理,直接丟棄該ack 。而接收端接收到了之后會(huì)再次回復(fù)ack 信息。

五、流量控制

上述中我們知道了TCP協(xié)議可以保證數(shù)據(jù)的可靠性,但是也得兼顧效率。兼顧效率的話(huà)需要考慮以下三個(gè)方面:

1.支持批量發(fā)包

2.能夠基于網(wǎng)絡(luò)的狀況,支持擁堵控制

3.能夠了解接收端的狀況,防止接收端處理不過(guò)來(lái)

基于以上三個(gè)需求,做了以下處理。

5.1、滑動(dòng)窗口

如果TCP 中的包,都需要發(fā)送一個(gè)確認(rèn)一個(gè)的話(huà),效率太低了,單次發(fā)送和確認(rèn)一個(gè)包,雖然保證了可靠性,但無(wú)法保證其效率。此時(shí)需要一個(gè)批量發(fā)送和確認(rèn)的方式,這就是滑動(dòng)窗口所做的事情。

發(fā)送滑動(dòng)窗口:

發(fā)送窗口從左向右移動(dòng)在這個(gè)發(fā)送窗口之前的數(shù)據(jù)必然是已經(jīng)發(fā)送而且得到接收方確認(rèn)的數(shù)據(jù)落在發(fā)送窗口之內(nèi)的數(shù)據(jù)是發(fā)送方可以發(fā)送的數(shù)據(jù)在發(fā)送窗口之后的數(shù)據(jù)是不能發(fā)送的數(shù)據(jù)。

如果發(fā)生超時(shí)或者丟失現(xiàn)象。那么有兩種解決方案:

1、回退N,丟失的包號(hào)之后所有包都重發(fā)

2、選擇重傳ARQ,只發(fā)丟失的,避免重復(fù)的(效率高,防止發(fā)送重復(fù)的)

滑動(dòng)窗口還有一個(gè)作用是讓發(fā)送端知道接收端的處理狀況。假設(shè)TCP接收方的緩存已經(jīng)滿(mǎn)了,無(wú)法處理更多的,而發(fā)送方并不知道,每次會(huì)給對(duì)方告知當(dāng)前滑動(dòng)窗口的大小值 ,此時(shí)發(fā)送端就不會(huì)再發(fā)送數(shù)據(jù)了。

1.接收方接收到數(shù)據(jù)同樣馬上發(fā)送確認(rèn),但是同時(shí)對(duì)發(fā)送方宣布窗口大小為0。這樣發(fā)送方就暫時(shí)不會(huì)發(fā)送數(shù)據(jù)。

2.報(bào)文到達(dá)時(shí)不馬上發(fā)送確認(rèn),直到緩存有足夠的空間。這樣就可以避免發(fā)送方滑動(dòng)窗口。但是這也存在一個(gè)問(wèn)題,接收方延遲發(fā)送確認(rèn)的時(shí)間不應(yīng)該超過(guò)超時(shí)時(shí)間,如果過(guò)長(zhǎng)會(huì)導(dǎo)致發(fā)送方誤以為數(shù)據(jù)丟失重新發(fā)送數(shù)據(jù)。

5.2、擁堵控制

我們知道網(wǎng)絡(luò)狀況有好友壞,好的時(shí)候,可以多發(fā)些包,壞的時(shí)候,如果發(fā)包速率不變的話(huà),除了會(huì)加重網(wǎng)路負(fù)擔(dān)以外,還會(huì)造成包的過(guò)多丟失,除非更多的超時(shí)重發(fā),這無(wú)疑識(shí)降低了通信效率。

基于此,TCP通信雙方維護(hù)一個(gè)叫做擁塞窗口(cwnd,congesion window)的值,這個(gè)值取決于網(wǎng)絡(luò)中的擁塞率,發(fā)送方的發(fā)送窗口的值就等于擁塞窗口的大小。只要網(wǎng)絡(luò)中沒(méi)有出現(xiàn)擁塞,擁塞窗口的值就可以增大一些,這樣發(fā)送方可以發(fā)送到網(wǎng)絡(luò)中的數(shù)據(jù)就多一些。反之,擁塞窗口的值就減小,從而避免加劇網(wǎng)絡(luò)的擁塞率。

TCP目前擁塞控制主要有以下4種算法:

1.慢啟動(dòng)

2.擁塞避免

3.快速重傳

4.快恢復(fù)

具體的算法實(shí)現(xiàn)方式就不再介紹了,大概實(shí)現(xiàn)的功能就是,基于當(dāng)前的網(wǎng)絡(luò)狀況,找到一個(gè)合適的發(fā)送速率,防止給網(wǎng)絡(luò)造成過(guò)大的負(fù)擔(dān)。比如說(shuō)慢啟動(dòng),就是開(kāi)始的時(shí)候,發(fā)送得較慢,然后根據(jù)丟包的情況,調(diào)整速率:如果不丟包,就加快發(fā)送速度;如果丟包,就降低發(fā)送速度。

六、TCP 狀態(tài)

了解TCP的都知道,TCP 建立連接的時(shí)候,有三次握手,斷開(kāi)鏈接的時(shí)候又四次握手交互。那么其中的狀態(tài)是有哪些?

上面的圖看著是不是太亂記不住,我們看看下面這張梳理一下,看看具體應(yīng)用狀態(tài)。

從上面可以看到,連接建立成功的時(shí)候,其狀態(tài)是ESTABLISHED 的。當(dāng)接受端的狀態(tài)為SYN—RECV的時(shí)候,表示接受端,已經(jīng)回復(fù)第二次握手信息了,等待發(fā)送端再次確認(rèn)。如果網(wǎng)絡(luò)中遭受到大量的SYN 攻擊,會(huì)存在大量的SYN_RECV 狀態(tài)。此時(shí)可以定位這些問(wèn)題IP ,通過(guò)防火墻過(guò)濾就能解決大量的假連接問(wèn)題。

七、消失的連接——TIME_WAIT

在網(wǎng)絡(luò)中,某一端主動(dòng)關(guān)閉而沒(méi)有通過(guò)四次握手關(guān)閉,此時(shí)tcp已經(jīng)建立的通道是否還在,多久會(huì)關(guān)閉?此時(shí)的TCP 狀態(tài)為T(mén)IME_WAIT ,可以想象,現(xiàn)實(shí)中經(jīng)常出現(xiàn)這種狀況,多數(shù)的關(guān)閉連接都是主動(dòng)關(guān)閉而非通過(guò)協(xié)商通信關(guān)閉。那么此時(shí)關(guān)閉,若果再重連還能重連上之前的tcp 通道么,還是需要重現(xiàn)創(chuàng)建。

任何TCP實(shí)現(xiàn)必須為MSL選擇一個(gè)值,默認(rèn)是2分鐘或者30秒,TIME_WAIT默認(rèn)是2倍的MSL,持續(xù)時(shí)間在1-4分鐘之間。MSL是IP數(shù)據(jù)包能在網(wǎng)絡(luò)中存活的最長(zhǎng)時(shí)間。

TIME_WAIT 存在的兩個(gè)理由:

1、可靠的實(shí)現(xiàn)TCP全雙工連接的終止

2、允許老的重復(fù)分節(jié)在網(wǎng)絡(luò)中消失

TCP必須防止某個(gè)連接的老的重復(fù)分組在該連接已經(jīng)終止后再現(xiàn),從而被誤解成屬于同一連接的化身,有time_wait 足夠長(zhǎng),是2倍的MSL的,那么足夠讓某個(gè)方向上的分組最多存活MSL秒就被丟棄。

從TIME_WAIT狀態(tài)到CLOSED狀態(tài),有一個(gè)超時(shí)設(shè)置,這個(gè)超時(shí)設(shè)置是 2*MSL(RFC793定義了MSL為2分鐘,Linux設(shè)置成了30s),如此超過(guò)了這個(gè)時(shí)間,當(dāng)前的tcp通道就會(huì)被定義為關(guān)閉。

以上就是淺析NIO系列之TCP的詳細(xì)內(nèi)容,更多關(guān)于NIO TCP的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MapReduce中ArrayWritable 使用指南

    MapReduce中ArrayWritable 使用指南

    MapReduce是一種編程模型,用于大規(guī)模數(shù)據(jù)集的并行運(yùn)算。概念"Map(映射)"和"Reduce(歸約)"和他們的主要思想,都是從函數(shù)式編程語(yǔ)言里借來(lái)的,還有從矢量編程語(yǔ)言里借來(lái)的特性。他極大地方便了編程人員在不會(huì)分布式并行編程的情況下,將自己的程序運(yùn)行在分布式系統(tǒng)上。
    2014-08-08
  • 一小時(shí)迅速入門(mén)Mybatis之bind與多數(shù)據(jù)源支持 Java API

    一小時(shí)迅速入門(mén)Mybatis之bind與多數(shù)據(jù)源支持 Java API

    這篇文章主要介紹了一小時(shí)迅速入門(mén)Mybatis之bind與多數(shù)據(jù)源支持 Java API,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Java實(shí)現(xiàn)簡(jiǎn)單的掃雷小程序

    Java實(shí)現(xiàn)簡(jiǎn)單的掃雷小程序

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單的掃雷小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 最新評(píng)論