做網(wǎng)站顏色如何搭配一個(gè)產(chǎn)品的網(wǎng)絡(luò)營銷方案
目錄
一、連接管理
二、三次握手
? ? ? ? 1、何為三次握手?
? ? ? ? 2、三次握手有何意義?
三、四次揮手
三次握手和四次揮手的相似之處和不同之處
? ?(1)相似之處
? ?(2)不同之處
四、TCP的狀態(tài)
建立連接:
斷開連接:
CMD控制平臺(tái)觀察上面介紹的狀態(tài)
LISTEN和ESTABLISHED
CLOSE_WAIT和TIME_WAIT
一、連接管理
? ? ? ? 正常情況下,TCP要經(jīng)歷“三次握手”建立連接,“四次揮手”斷開連接。
????????TCP是有連接的,我們程序員編寫客戶端代碼時(shí),只要:socket = new Socket(String serverIP, int serverPort),操作系統(tǒng)內(nèi)核中就會(huì)自動(dòng)和服務(wù)器建立連接,如圖:
? ? ? ? 內(nèi)核是怎么完成上述建立連接的過程的呢?——三次握手
? ? ? ? 而當(dāng)要斷開連接時(shí),內(nèi)核是怎么進(jìn)行的呢?——四次揮手
二、三次握手
? ? ? ? 1、何為三次握手?
? ? ? ? 在建立連接的過程中,客戶端一定是主動(dòng)的一方,第一次交互就是客戶端發(fā)起的,客戶端首先要發(fā)送給服務(wù)器syn(同步報(bào)文段),然后服務(wù)器收到 syn 后,服務(wù)器就會(huì)發(fā)送ack(應(yīng)答報(bào)文),然后服務(wù)器也要發(fā)送 syn 給客戶端,客戶端在收到 syn 后,就會(huì)返回一個(gè) ack 給服務(wù)器,這是,三次握手的就完成了,如圖:
? ? ? ? 上面畫的好像是四次交互啊,那為啥稱為三次握手呢?原因很簡(jiǎn)單,因?yàn)榉?wù)器給客戶端發(fā)送的兩個(gè)報(bào)文,可以合并成一個(gè)也就是ack+syn。為什么呢?想象一下,我們網(wǎng)購的時(shí)候,同時(shí)買了兩份商品,商家是不是就會(huì)把這兩份商品打包成一件商品,一起郵寄給我們,原因很簡(jiǎn)單,就是節(jié)省成本。網(wǎng)絡(luò)中也是如此,反正ack和syn都要發(fā)到客戶端中,那為什么不直接打包成一份呢?何況網(wǎng)絡(luò)傳輸是要經(jīng)過層層封裝、分用,多一個(gè)次傳輸,傳輸成本就會(huì)增加好多,也就成了三次握手,如下圖:
? ? ? ? 除了節(jié)約成本外,還有一個(gè)原因(也是能合并的前提):ack和syn的觸發(fā)時(shí)機(jī)是一樣的,所以可以把這兩個(gè)合并在一起。所以100%會(huì)合并!
? ? ? ? 這里客戶端在第一次交互中,雖然已經(jīng)發(fā)送給服務(wù)器syn了,但是服務(wù)器是否要保存客戶端的信息,還得觀望觀望,等這三次握手結(jié)束后,才能保存客戶端的信息,確立連接,以及后續(xù)的通信。
? ? ? ? 這里的第一次交互,服務(wù)器收到客戶端發(fā)來的syn,服務(wù)器會(huì)有兩種情況:一、服務(wù)器同意,表示服務(wù)器也愿意和客戶端建立連接;二、服務(wù)器不同意,這種情況很少出現(xiàn),一般的原因就是服務(wù)器的負(fù)載極高,已經(jīng)處理不過來了,客戶端發(fā)來的請(qǐng)求處理不過來了,服務(wù)器完全無法響應(yīng),就沒有下文了。
? ? ? ? 因?yàn)?strong>服務(wù)器是提供服務(wù)的,所以客戶端發(fā)來的請(qǐng)求就一定會(huì)盡可能的處理,返回響應(yīng),所以一般都會(huì)同意客戶端的建立請(qǐng)求。
????????? ? ? ? 握手的英譯:handshake,是一個(gè)形象的比喻,握手只是打招呼,不用商討具體的細(xì)節(jié)(業(yè)務(wù)邏輯,也就是應(yīng)用程序 / 應(yīng)用層要完成的事情)。其中這里就是簡(jiǎn)單的建立個(gè)連接而已,沒有其他操作,還有三次握手也會(huì)有超時(shí)重傳,三次握手結(jié)束后,超時(shí)重傳也還存在。
syn的介紹:所謂的syn就是一個(gè)特殊的TCP數(shù)據(jù)報(bào)
? ? ? ? syn是六個(gè)標(biāo)志位的第五位,全稱:synchronize ,表示同步的意思,如圖:
? ? ? ? 表達(dá)的語義:我想和你建立連接。這里的 syn 雖然不帶有應(yīng)用層載荷,但也會(huì)帶有 IP報(bào)頭?/ 以太網(wǎng)數(shù)據(jù)幀等等,更會(huì)有TCP報(bào)頭,其中TCP報(bào)頭中就包含了客戶端自己的端口,IP報(bào)頭中就包含了客戶端的IP。
? ? ? ? 2、三次握手有何意義?
(1)投石問路,確認(rèn)客戶端和服務(wù)器之間的通信通道是否“通暢”
? ? ? ? 比如地鐵,地鐵每天的第一趟不是載客的,而是先空車跑一趟,確認(rèn)列車是否能正常運(yùn)行到目的地,中間是否會(huì)有故障;而三次握手也是有類似的功能,通信前先確認(rèn)通信鏈路是否是通暢的,有一種投石問路的效果。
(2)三次握手,也是在確定通信雙方是否能發(fā)送信息和接受信息(接受和發(fā)送能力是否正常)
? ? ? ? 功能和上面畫的圖一樣,如圖:
? ? ? ? 第一次交互,客戶端先給服務(wù)器發(fā)送syn建立請(qǐng)求,服務(wù)器收到了syn后,就知道客戶端的發(fā)送能力是沒有問題的;第二次交互,服務(wù)器發(fā)送ack+syn給客戶端,當(dāng)客戶端收到后,客戶端就知道了,自己的發(fā)送能力沒有問題,服務(wù)器的接受和發(fā)送能力沒有問題;第三次交互,客戶端發(fā)送ack給服務(wù)器,服務(wù)器收到ack,服務(wù)器就能知道,自己的發(fā)送能力和接受能力都沒有問題,還有客戶端的接受能力也沒有問題。
(3)建立連接的過程也會(huì)協(xié)商一些參數(shù)
? ? ? ? 因?yàn)榫W(wǎng)絡(luò)通信是客戶端和服務(wù)器兩方的事情,所以就要配合,就要協(xié)商一些信息,保證其中的有些內(nèi)容要一樣。
? ? ? ? TCP協(xié)議中也有很多參數(shù)是要客戶端和服務(wù)器雙方進(jìn)行協(xié)商的,這些內(nèi)容往往體現(xiàn)在 選項(xiàng)中,如圖
? ? ? ? 其中有一個(gè)信息是挺關(guān)鍵的:TCP 的通信序號(hào),如圖:
? ? ? ? 也是因?yàn)榫W(wǎng)絡(luò)傳輸中:后發(fā)先至(先發(fā)后至)的情況是普遍存在的,所以要引入序號(hào)這一概念。為了區(qū)分不同連接之間的數(shù)據(jù)包。
? ? ? ? TCP在通信過程中,序號(hào)不是從 0 / 1開始的,而是選擇一個(gè)比較大的數(shù)字,以這個(gè)數(shù)字開頭來計(jì)算,即使是同一個(gè)客戶端和服務(wù)器,每次連接,開始的序號(hào)都不同,原因:避免“前朝的件,斬本朝的官”。啥意思,如圖:
? ? ? ? 所以,第二次連接,舊的數(shù)據(jù)應(yīng)該丟棄。而舊的數(shù)據(jù)包也能一眼就看出來,原因就是每次連接(就算是同一客戶端和服務(wù)器的連接),每次開始的序號(hào)也會(huì)不同,就很容易區(qū)別新舊數(shù)據(jù)包,把舊的數(shù)據(jù)包丟棄。
? ? ? ? 比如清朝的人,和我們現(xiàn)代人走在一起,想象清朝的人是“大粽子”,是不是一眼就能看出來他“不是人”(doge)。
三、四次揮手
? ? ? ? 連接的過程,本質(zhì)是在于服務(wù)器和客戶端直接能保存對(duì)端的信息,是虛擬的連接,而這些信息是要放在數(shù)據(jù)結(jié)構(gòu)中的。
? ? ? ? 斷開連接的過程,本質(zhì)就在于把服務(wù)器和客戶端里保存的對(duì)端的信息,在數(shù)據(jù)結(jié)構(gòu)上給釋放掉,是邏輯上的斷開連接,也是虛擬的。
? ? ? ? 其中四次揮手有點(diǎn)類似現(xiàn)實(shí)中的離婚的“和離”(和平分手),因?yàn)榻Y(jié)婚領(lǐng)證后是具有法律效應(yīng)的,如果要離婚,就會(huì)牽扯到財(cái)產(chǎn)糾紛問題,并不是其中的一方想離就立即能離的,一般要確認(rèn)財(cái)產(chǎn)分配問題,雙方的觀念達(dá)成一致,才能離成,這種情況就是“和離”;而四次揮手呢,也并不是客戶端和服務(wù)器的其中一端的單方面情況,想斷開連接就斷開連接,而是要遵循一些約定,經(jīng)過四次揮手的過程后,才能斷開連接。
? ? ? ? 那么四次揮手的過程是咋樣的呢?(斷開連接并不像建立連接,發(fā)送端一定是客戶端,斷開連接的發(fā)起者,可以是服務(wù)器,也可以是客戶端)大概流程如圖:
? ? ? ? 這里就涉及到四次交互,其中服務(wù)器這邊,是不可以把a(bǔ)ck和fin進(jìn)行合并!!一起發(fā)送給客戶端的,為什么呢,原因就是:服務(wù)器這邊的ack和fin觸發(fā)時(shí)機(jī)是不一樣的!服務(wù)器接受到對(duì)端的fin時(shí),就會(huì)立即發(fā)送ack給對(duì)端,而fin要經(jīng)歷一些程序員寫的一些代碼,一些邏輯后,才能執(zhí)行服務(wù)器這邊的代碼: socket.close(),才會(huì)給對(duì)端發(fā)fin。當(dāng)然也不是絕對(duì)的,如果服務(wù)器這邊的如果斷開連接的代碼很少,fin和發(fā)送ack的觸發(fā)時(shí)機(jī)幾乎是同一時(shí)間,這時(shí)候服務(wù)器當(dāng)然也可以把a(bǔ)ck+fin合并到一起再發(fā)送給對(duì)端啦。所以,中間兩次可以合并嗎?我們稱為?:如合!
? ? ? ? 上面這四次交互,就是四次揮手的過程了。
三次握手和四次揮手的相似之處和不同之處
? ?(1)相似之處
? ? ? ? 傳輸順序是相似的,都是各自給對(duì)端發(fā)生 syn / fin,對(duì)端返回ack,然后對(duì)端再發(fā)送 syn / fin ,? ?當(dāng)前端再返回回去ack。
? ? ? ? 三次握手交互順序:syn / ack / syn / ack
? ? ? ? 四次揮手交互順序:fin / ack / fin /ack
? ?(2)不同之處
? ? ? ? 發(fā)送方的約定不同,三次握手的發(fā)送方(主動(dòng)方)必須是客戶端,四次揮手的發(fā)送方雙方(主動(dòng)方)都可以。
四、TCP的狀態(tài)
? ? ? ? 下圖是TCP狀態(tài)轉(zhuǎn)換的匯總:
? ? ? ? 這里主要介紹四個(gè)常用的狀態(tài)。
建立連接:
????????LISTEN狀態(tài):在Linux系統(tǒng)是LISTEN,Windows系統(tǒng)是LISTENING;表示服務(wù)器這邊已經(jīng)創(chuàng)建好ServerSocket了,并且已經(jīng)好綁定IP地址和端口了,隨時(shí)可以接收客戶端發(fā)來的請(qǐng)求。
????????ESTABLISHED狀態(tài):表示三次握手的過程已經(jīng)結(jié)束了,客戶端和服務(wù)器之間已經(jīng)建立好連接了。
斷開連接:
????????CLOSE_WAIT狀態(tài):表示被動(dòng)方的這一端,收到了對(duì)端發(fā)來的fin后,會(huì)進(jìn)入這個(gè)狀態(tài)。
????????TIME_WAIT狀態(tài):表示主動(dòng)方這一端,發(fā)送給對(duì)端fin后,對(duì)端也發(fā)送fin給我后,本端會(huì)處于這個(gè)狀態(tài),就是為了給最后一個(gè)ack的重傳留有一定時(shí)間。
CMD控制平臺(tái)觀察上面介紹的狀態(tài)
首先,啟動(dòng)我們之前寫的TCP代碼,啟動(dòng)這服務(wù)器和客戶端。
詳細(xì)代碼在:網(wǎng)絡(luò)編程套接字(4)——Java套接字(TCP協(xié)議)-CSDN博客
其中服務(wù)器和客戶端的端口和地址,如圖:
LISTEN和ESTABLISHED
只啟動(dòng)服務(wù)器
????????在CMD控制平臺(tái)輸入:netstat -ano | findstr 9090
? ? ? ? 第一列是協(xié)議,第二列是本地地址,第三列是外部地址,第四列是狀態(tài),第五列是 PID。
????????其中,這里0.0.0.0是本機(jī)所有網(wǎng)絡(luò)接口的地址,是本網(wǎng)絡(luò)中的本機(jī),也就是說,表示當(dāng)前設(shè)備上所有可用的IP地址,也稱為通配地址。而127.0.0.1是回環(huán)地址,是為了讓本機(jī)能夠?qū)崿F(xiàn)自我測(cè)試和自我通信。
? ? ? ? 方括號(hào)是IPV6的地址。
? ? ? ? 服務(wù)器的端口號(hào)是9090,也就是服務(wù)器的地址,當(dāng)前狀態(tài)是LISTENING,表示服務(wù)器已經(jīng)綁定好了IP地址和端口,隨時(shí)可以和客戶端建立連接。
? ? ? ? 大概流程如下圖:
啟動(dòng)服務(wù)器和客戶端
? ? ? ? 在CMD控制平臺(tái)輸入:netstat -ano | findstr 9090
? ? ? ? 客戶端是第三行,服務(wù)器是第二行,其中它們的狀態(tài)都變成了ESTABLISHED,表示服務(wù)器和客戶端兩端已經(jīng)建立了聯(lián)系。
CLOSE_WAIT和TIME_WAIT
? ? ? ? 在Windows操作系統(tǒng),CLOSE_WAIT和TIME_WAIT是不容易被觀察到的,用CMD控制平臺(tái)看不到這個(gè)狀態(tài)。
? ? ? ? 其中,這里TIME_WAIT是為了給最后一個(gè)ack重傳留有一定的時(shí)間。其中,最后一個(gè)ack要發(fā)送給服務(wù)器,客戶端和服務(wù)器之間,在數(shù)據(jù)結(jié)構(gòu)中保存的對(duì)端信息才能被釋放掉,如果最后一個(gè)ack丟包了,客戶端這邊也不知道是啥情況,就可以使用TIME_WAIT狀態(tài)進(jìn)行標(biāo)記,如果ack丟包了,就等一定的時(shí)間,給客戶端這邊重傳ack提供保障。
? ? ? ? 當(dāng)然,這里也不是無休止的等,是有一定是時(shí)間限制的,最多等2MSL(MSL是一個(gè)系統(tǒng)內(nèi)核的配置項(xiàng),表示服務(wù)器和客戶端之間消耗最多的時(shí)間,常見的設(shè)置值是2 min),這里如果等了2MSL,還沒收到客戶端發(fā)來的ack,也意味著客戶端這邊不可能會(huì)發(fā)ack過來了,再也不會(huì)重傳了,就直接斷開連接吧,丟棄一些在數(shù)據(jù)結(jié)構(gòu)中的信息。
? ? ? ? 一般而言,對(duì)于服務(wù)器出現(xiàn)大量的CLOSE_WAIT狀態(tài),原因就是服務(wù)器沒有正確關(guān)閉socket,導(dǎo)致四次揮手沒有正確完成,這是應(yīng)該BUG;只需要加上對(duì)應(yīng)的close即可。