自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

從TCP協(xié)議到TCP通信的各種異常現(xiàn)象和分析(下)

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
今天我們繼續(xù)介紹關(guān)于TCP異常情況的內(nèi)容,本篇文章重點介紹的是在數(shù)據(jù)傳輸過程中的各種異常,以及出現(xiàn)異常后的TCP連接的情況。

今天我們繼續(xù)介紹關(guān)于TCP異常情況的內(nèi)容。本篇文章接著上一篇文章,前面分析了在連接過程中的各種異常,本篇文章重點介紹的是在數(shù)據(jù)傳輸過程中的各種異常,以及出現(xiàn)異常后的TCP連接的情況。為了便于大家理解本文,這里我們將上一篇文章的前半部分內(nèi)容拷貝到這里,這部分內(nèi)容主要介紹協(xié)議的內(nèi)容。

下圖是網(wǎng)絡(luò)通信中常見的架構(gòu),也就是CS架構(gòu)。其中程序包括兩部分,分別為客戶端(Client)和服務(wù)端(Server)。當然,實際的環(huán)境還要復(fù)雜的多,在客戶端和服務(wù)端之間可能有多種不同種類和數(shù)量的設(shè)備,這些設(shè)備都會增加網(wǎng)絡(luò)通信的復(fù)雜性。自然,也會增加程序開發(fā)容錯的復(fù)雜性。

理解了這些異?,F(xiàn)象才敢說真正懂了TCP協(xié)議(下)

圖1 基本架構(gòu)

一、TCP的基本流程

在分析異常情況之前,我們先回憶一下TCP協(xié)議的基本邏輯。在客戶端和服務(wù)端能夠收發(fā)數(shù)據(jù)之前首先必需建立連接。連接的建立在協(xié)議層面也是通過收發(fā)數(shù)據(jù)包完成,只不過在用戶層面就是客戶端調(diào)用了一個connect函數(shù)。連接的過程俗稱“三次握手”,具體流程如圖2所示。

理解了這些異常現(xiàn)象才敢說真正懂了TCP協(xié)議(下)

圖2 TCP的三次握手流程

TCP連接的斷開也是比較復(fù)雜的,需要經(jīng)過所謂的“四次揮手”的流程。其原因是因為TCP是雙工通信,分別需要從客戶端和服務(wù)端2側(cè)斷開連接。

理解了這些異?,F(xiàn)象才敢說真正懂了TCP協(xié)議(下)

圖3 TCP的四次揮手

另外一個比較重要的內(nèi)容是TCP協(xié)議的狀態(tài)轉(zhuǎn)換,理解了這個內(nèi)容,我們才能清楚出現(xiàn)各種異常情況下數(shù)據(jù)包的內(nèi)容。

理解了這些異?,F(xiàn)象才敢說真正懂了TCP協(xié)議(下)

圖4 TCP狀態(tài)轉(zhuǎn)換圖

本文只是簡單回憶一下TCP的基本流程,詳細的內(nèi)容可以參考本號之前的文章《從TCP到Socket,徹底理解網(wǎng)絡(luò)編程是怎么回事

二、異常情況分析

本文的分析假設(shè)連接已經(jīng)建立,目前正在數(shù)據(jù)收發(fā)過程。這種情況下會出現(xiàn)各種異常,比如服務(wù)器宕機、進程crash或者進程被kill等等。下面我們分別介紹上述集中情況在TCP通信中的表現(xiàn)。

1. 服務(wù)進程crash

服務(wù)進程crash恐怕是我們?nèi)粘I森h(huán)境最長遇到的情況,沒有之一吧。那么在這種情況下客戶端軟件是什么反應(yīng)?客戶端是否可以感知?

我們分別寫客戶端和服務(wù)端的程序,客戶端不斷的發(fā)送數(shù)據(jù),服務(wù)端接收數(shù)據(jù)。異常的模擬很簡單,我們可以在服務(wù)端制造一個指針訪問異常。此時服務(wù)端的程序就會crash掉。然后我們觀察客戶端的表現(xiàn)。先上結(jié)果,客戶端的表現(xiàn)如下圖所示。

理解了這些異常現(xiàn)象才敢說真正懂了TCP協(xié)議(下)

可以看到客戶端被reset掉了。我們在結(jié)合通過wireshark抓獲的此時的數(shù)據(jù)報文內(nèi)容,可以看到是一個RST報文。

理解了這些異?,F(xiàn)象才敢說真正懂了TCP協(xié)議(下)

回憶一下什么情況下服務(wù)端會發(fā)送RST報文。這種場景跟我們前文介紹的服務(wù)端沒有監(jiān)聽的情況是類似的。由于服務(wù)端程序crash了,此時在操作系統(tǒng)中的套接字數(shù)據(jù)結(jié)構(gòu)已經(jīng)被釋放,因此在協(xié)議層收到數(shù)據(jù)包的時候無法找到對應(yīng)的套接字進行處理,于是發(fā)送了一個RST報文。

2. 手動殺死服務(wù)端應(yīng)用

這也是線上比較常見的操作,當一個模塊上線時,ops同學(xué)總是會先把舊的進程殺死,然后再啟動新的進程。那么在這個過程中TCP連接又會發(fā)生了什么呢?是否會像上一種情況一樣被RST呢?同樣,我們先看一下結(jié)果,如下是客戶端的情況。

理解了這些異?,F(xiàn)象才敢說真正懂了TCP協(xié)議(下)

從上面錯誤碼來看是管道破裂,其實也就是連接被中斷了。我們再看一下通過wireshark的抓包結(jié)果可以看出服務(wù)端發(fā)送了一個FIN報文,這個報文表示服務(wù)端發(fā)起了關(guān)閉的請求。而接下來的一個報文是客戶端對該請求的確認。

理解了這些異?,F(xiàn)象才敢說真正懂了TCP協(xié)議(下)

所以,從上面客戶端的錯誤碼和報文情況我們可以知道,在kill進程時TCP協(xié)議是能夠感知到的,并且發(fā)送的FIN報文。

我們再進一步的思考一下,為什么kill進程會有FIN呢?這個與前面crash的差異在哪?其實kill進程是通過shell想內(nèi)核發(fā)送了SIGKILL或者SIGTERM,內(nèi)核接收到該信號之后會進行相應(yīng)的掃尾工作,因此可以看到服務(wù)端發(fā)送了FIN報文。

3. Server進程所在的主機關(guān)機

主機關(guān)機(這里指手動關(guān)機)的情況與進程被kill是類似的。這時因為在系統(tǒng)關(guān)閉時,init進程會給所有進程發(fā)送SIGTERM信號,等待一段時間(5~20秒),然后再給所有仍在運行的進程發(fā)送SIGKILL信號。當服務(wù)器進程死掉時,會關(guān)閉所有文件描述符。帶來的影響和上面殺死server相同。

4. Server進程所在的主機宕機

這是我們線上另一種比較常見的狀況。即使宕機是一個小概率事件,線上幾千臺服務(wù)器動不動一兩臺掛掉也是常有的事。這里掛掉其實包括2種情況,一種是內(nèi)核panic,另外一種情況是出現(xiàn)了掉電。對于內(nèi)核panic的情況不會像關(guān)機那樣會預(yù)先殺死上面的進程,而是突然性的。那么此時我們的客戶端準備給服務(wù)器端發(fā)送一個請求,它由write寫入內(nèi)核,由TCP作為一個報文發(fā)出,但因為主機已經(jīng)掛掉,因此客戶端無法收到ACK。于是客戶端TCP持續(xù)重傳分節(jié),試圖從服務(wù)器上接收一個ACK,然而服務(wù)器始終不能應(yīng)答,重傳數(shù)次之后,大約幾分鐘才停止,之后返回一個ETIMEDOUT錯誤。在這種情況下,如果我們調(diào)用的是同步發(fā)送接口,則在發(fā)送緩沖區(qū)慢的情況下會阻塞在這里,導(dǎo)致程序阻塞。

這個時間真的很長,對于某些應(yīng)用這種長時間的卡頓是不能接受的。因此,需要一種手段處理這種情況,在套接字接口中可以通過SO_SNDTIMEO標記進行設(shè)置。但是有利也有弊,如果設(shè)置了該參數(shù),可能會出現(xiàn)這的數(shù)據(jù)發(fā)送超時的情況,進而出現(xiàn)向服務(wù)端發(fā)送重復(fù)數(shù)據(jù)的情況,此時需要服務(wù)端做去重處理。

5. 服務(wù)器進程所在的主機宕機后重啟

在客戶端發(fā)出請求前,服務(wù)器端主機經(jīng)歷了宕機—重啟的過程。當客戶端TCP把分節(jié)發(fā)送到服務(wù)器端所在的主機,服務(wù)器端所在主機的TCP丟失了崩潰前所有連接信息,即TCP收到了一個根本不存在連接上(也就是我們前文介紹的查找不到socket數(shù)據(jù)結(jié)構(gòu))的報文,所以會響應(yīng)一個RST分節(jié)。

至此,關(guān)于TCP協(xié)議中各種異常情況介紹完了,詳細了解這些內(nèi)容后對后續(xù)線上問題的分析和解決會有很大的幫助。當然,也有可能還有其它本文沒有介紹到的異常情況,也歡迎大家留言交流。

責任編輯:趙寧寧 來源: 今日頭條
相關(guān)推薦

2019-05-16 15:19:40

TCP協(xié)議TCP通信三次握手

2019-05-17 09:02:19

TCP協(xié)議服務(wù)端

2019-05-28 09:40:39

TCP協(xié)議socket接口

2010-06-08 14:43:48

2018-12-03 05:54:48

Wireshark網(wǎng)絡(luò)協(xié)議TCP

2010-06-12 15:41:29

TCP IP通信協(xié)議

2010-06-12 15:54:09

TCP IP協(xié)議

2017-08-16 11:00:38

TCPIP協(xié)議

2010-03-09 14:10:13

Python循環(huán)語句

2017-10-25 20:52:03

內(nèi)核權(quán)限空指針異常

2019-04-29 10:26:49

TCP網(wǎng)絡(luò)協(xié)議網(wǎng)絡(luò)通信

2010-02-23 18:05:40

WCF異常現(xiàn)象

2019-03-12 10:46:17

TCP協(xié)議算法

2010-06-09 14:42:21

UDP協(xié)議TCP協(xié)議

2010-06-09 11:38:37

傳輸層通信協(xié)議

2010-07-06 15:50:12

TCP和UDP協(xié)議

2010-06-13 15:32:57

TCP協(xié)議

2010-09-27 13:25:58

TCP IP協(xié)議棧

2013-05-27 10:48:16

TCPUDP傳輸協(xié)議

2020-07-28 08:38:10

TCPUDP協(xié)議
點贊
收藏

51CTO技術(shù)棧公眾號