新聞中心
TCP是網(wǎng)絡(luò)傳輸控制協(xié)議,廣泛應(yīng)用于互聯(lián)網(wǎng)中。而TCP RST是指TCP連接復(fù)位報文,它的作用是終止一個TCP連接。本文將介紹TCP RST的作用和原因。

一、背景
在TCP連接的建立過程中,當(dāng)客戶端向服務(wù)端發(fā)起連接請求,并收到服務(wù)端的確認(rèn)后,TCP連接將建立起來,兩邊可以像“打”一樣通信。在這種情況下,TCP連接的狀態(tài)被稱為“正常連接”。
在正常連接中,客戶端和服務(wù)端會互相向?qū)Ψ桨l(fā)送數(shù)據(jù)報文,來進(jìn)行通信。但是有時候,當(dāng)某一端因為某種原因無法處理對方發(fā)送過來的數(shù)據(jù)時,它就會發(fā)送一個TCP RST報文,來終止這個連接。TCP RST在網(wǎng)絡(luò)安全領(lǐng)域也有很重要的作用,它可以用于拒絕攻擊者的惡意連接。
二、TCP RST的作用
1. 終止TCP連接
TCP RST報文可以直接強(qiáng)制終止一個TCP連接。當(dāng)一個TCP連接的一端無法處理另一端發(fā)送過來的數(shù)據(jù),它就會發(fā)送一個TCP RST報文,來終止這個連接。一般情況下,RST報文是由客戶端或服務(wù)端發(fā)送的,但在某些情況下,操作系統(tǒng)也可以使用RST作為一種重置TCP連接狀態(tài)的手段。
2. 避免服務(wù)拒絕攻擊(DoS)
TCP RST報文在拒絕服務(wù)攻擊(DoS)防范中也發(fā)揮了重要作用。攻擊者可能會通過發(fā)送大量的數(shù)據(jù)來占用目標(biāo)主機(jī)的帶寬和資源,從而使服務(wù)無法正常運行。這時,目標(biāo)主機(jī)就可以發(fā)送一個RST報文,來終止攻擊者與目標(biāo)主機(jī)之間的TCP連接,以保護(hù)服務(wù)正常運行。
3. 系統(tǒng)資源的釋放
當(dāng)一個TCP連接在正常關(guān)閉后,會等待一段時間(通常是幾分鐘),以確保對方已經(jīng)收到并處理了所有數(shù)據(jù)。如果這段時間內(nèi)沒有數(shù)據(jù)來往,那么操作系統(tǒng)就會自動釋放用于該連接的資源(如緩存、端口等)。但是,在某些情況下,當(dāng)操作系統(tǒng)檢測到連接已經(jīng)無法回收或資源無法釋放時,會發(fā)送一條RST報文來中止該連接,以便盡早釋放系統(tǒng)資源。
三、TCP RST的原因
1. TCP套接字異常關(guān)閉
TCP套接字的異常關(guān)閉可能產(chǎn)生RST報文。例如,當(dāng)主機(jī)因突然斷電等不可預(yù)知因素而宕機(jī)后,TCP套接字可能會異常關(guān)閉,這時TCP協(xié)議棧就可能會自動發(fā)送RST報文來中止任何正在進(jìn)行的連接。
2. TCP應(yīng)用程序主動關(guān)閉連接
當(dāng)TCP應(yīng)用程序認(rèn)為連接已經(jīng)完成并要求關(guān)閉連接時,它可能會發(fā)送一個FIN(結(jié)束)報文來告知對方連接即將關(guān)閉。如果另一端忽略了這個FIN報文,那么TCP協(xié)議棧就會發(fā)送一個RST報文,以終止該連接。
3. TCP連接超時
當(dāng)TCP連接超時,操作系統(tǒng)可能會自動發(fā)送RST報文,以的更大值大于或等于240秒。如果超過了這個時間,TCP連接可能會作系統(tǒng)強(qiáng)制終止。
四、
TCP RST是終止TCP連接的報文。它可以用于關(guān)閉異常套接字、處理TCP應(yīng)用程序關(guān)閉連接的問題、避免拒絕服務(wù)攻擊等。知道RST的應(yīng)用場景和原因,可以幫助我們更好地了解TCP協(xié)議的工作方式,進(jìn)而更好地理解Linux操作系統(tǒng)的網(wǎng)絡(luò)運行機(jī)制。
相關(guān)問題拓展閱讀:
- 套接字建立連接過程
套接字建立連接過程
要創(chuàng)建一個可用的套接字,需要使用下面的函數(shù):
domain 就是指 PF_INET、PF_INET6 以及 PF_LOCAL 等,表示什么樣掘轎迅的套接字。
type 可用的值是:
參數(shù) protocol 原本是用來指定通信協(xié)議的,但現(xiàn)在基本廢棄。因為協(xié)議已經(jīng)通過前面兩個參數(shù)指定完成。protocol 目前一般寫成 0 即可。
創(chuàng)建出來的套接字如果需要被別人使用,就需要調(diào)用 bind 函數(shù)把套接字和套接字地址綁定.調(diào)用 bind 函數(shù)的方式如下:
我們需要注意到 bind 函數(shù)后面的第二個參數(shù)是通用地址格式sockaddr * addr。這里有一個地方值得注意,那就是雖然接收的是通用地址格式,實際上傳入的參數(shù)可能是 IPv4、IPv6 或者本地套接字格式。bind 函數(shù)會根據(jù) len 字段判斷傳入的參數(shù) addr 該怎么解析,len 字段表示的就是傳入的地址長度,它是一個可變值。
這里其實可以把 bind 函數(shù)理解成這樣:
不過 BSD 設(shè)計套接字的時候大約是 1982 年,那個時候的 C 語言還沒有void *的支持,為了解決這個問題,BSD 的設(shè)計者們創(chuàng)造性地設(shè)計了通用地址格式來作為支持 bind 和 accept 等這些函數(shù)的參數(shù)。
對于使用者來說,每次需要將 IPv4、IPv6 或者本地套接字格式轉(zhuǎn)化為通用套接字格式,就像下面的 IPv4 套接字地址格式的例子一樣:
對于實現(xiàn)者來說,可根據(jù)該地址結(jié)構(gòu)的前兩個字節(jié)判斷出是哪種地址。為了處理長度可變的結(jié)構(gòu),需要讀取函數(shù)里的第三個參數(shù),也就是 len 字段,這樣就可以對地址進(jìn)行解析和判斷了。
我們可以把地址設(shè)置成本機(jī)的 IP 地址,這相當(dāng)告訴操作系統(tǒng)內(nèi)核,僅僅對目標(biāo) IP 是本機(jī) IP 地址的 IP 包進(jìn)行處理。但是這樣寫的程序在部署時有一個問題,我們編寫應(yīng)用程序時并不清楚自己的應(yīng)用程序?qū)徊渴鸬侥呐_機(jī)器上。這個時候,可以利用通配地址的能力幫助我們解決這個問題。通配地址相當(dāng)于告訴操作系統(tǒng)內(nèi)核:“Hi,我可不挑活,只要目標(biāo)地址是咱們的都可以?!北热缫慌_機(jī)器有兩塊網(wǎng)卡,IP 地址分別是 202.61.22.55 和 192.168.1.11,那么向這兩個 IP 請求的請求包都會帆納被我們編寫的應(yīng)用程序處理。
那么該如何設(shè)置通配地址呢?
對于 IPv4 的地址來說,使用 INADDR_ANY 來完成通配地址的設(shè)置;對于 IPv6 的地址來說,使用 IN6ADDR_ANY 來完成通配地址的設(shè)置。
除了地址,還有端口。如果把端口設(shè)置成 0,就相當(dāng)于把端口的選擇權(quán)交給操作系統(tǒng)內(nèi)核來處理,操作系統(tǒng)內(nèi)核會根據(jù)一定的算法選擇一個空閑的端口,完成套接字的綁定。這在服務(wù)器端不常使用。
我們來看一個初始化 IPv4 TCP 套接字的例子:
初始化創(chuàng)建的套接字,可以認(rèn)為是一個”主動”套接字,其目的是之后主動發(fā)起請求(通過調(diào)用 connect 函數(shù),后面會講到)。通過 listen 函數(shù),可以將原來的”主動”套接字轉(zhuǎn)換為”被動”套接字,告訴操作系統(tǒng)內(nèi)核:“我這個套接字是用來等待用戶請求的。”當(dāng)然,操作系統(tǒng)內(nèi)核會為此做好接收用戶請求的一切準(zhǔn)備,比如完成連接隊列。
listen 函數(shù)的原型是這樣的:
我來稍微解釋一下。之一個參數(shù) socketfd 為套接字描述符,第二個參數(shù) backlog,官方的解釋判此為未完成連接隊列的大小,這個參數(shù)的大小決定了可以接收的并發(fā)數(shù)目。這個參數(shù)越大,并發(fā)數(shù)目理論上也會越大。但是參數(shù)過大也會占用過多的系統(tǒng)資源,一些系統(tǒng),比如 Linux 并不允許對這個參數(shù)進(jìn)行改變。對于 backlog 整個參數(shù)的設(shè)置有一些更佳實踐,這里就不展開,后面結(jié)合具體的實例進(jìn)行解讀
accept 這個函數(shù)的作用就是連接建立之后,操作系統(tǒng)內(nèi)核和應(yīng)用程序之間的橋梁。它的原型是:
函數(shù)的之一個參數(shù) listensockfd 是套接字,可以叫它為 listen 套接字,因為這就是前面通過 bind,listen 一系列操作而得到的套接字。函數(shù)的返回值有兩個部分,之一個部分 cliadd 是通過指針方式獲取的客戶端的地址,addrlen 告訴我們地址的大小,這可以理解成當(dāng)我們拿起機(jī)時,看到了來電顯示,知道了對方的號碼;另一個部分是函數(shù)的返回值,這個返回值是一個全新的描述字,代表了與客戶端的連接。
這里一定要注意有兩個套接字描述字,之一個是監(jiān)聽套接字描述字 listensockfd,它是作為輸入?yún)?shù)存在的;第二個是返回的已連接套接字描述字。
你可能會問,為什么要把兩個套接字分開呢?用一個不是挺好的么?
監(jiān)聽套接字一直都存在,它是要為成千上萬的客戶來服務(wù)的,直到這個監(jiān)聽套接字關(guān)閉;而一旦一個客戶和服務(wù)器連接成功,完成了 TCP 三次握手,操作系統(tǒng)內(nèi)核就為這個客戶生成一個
已連接套接字
,讓應(yīng)用服務(wù)器使用這個已連接套接字和客戶進(jìn)行通信處理。如果應(yīng)用服務(wù)器完成了對這個客戶的服務(wù),比如一次網(wǎng)購下單,一次付款成功,那么關(guān)閉的就是已連接套接字,這樣就完成了 TCP 連接的釋放。請注意,這個時候釋放的只是這一個客戶連接,其它被服務(wù)的客戶連接可能還存在。最重要的是,
監(jiān)聽套接字
一直都處于“監(jiān)聽”狀態(tài),等待新的客戶請求到達(dá)并服務(wù)。
前面講述的 bind、listen 以及 accept 的過程,是典型的服務(wù)器端的過程。下面我來講下客戶端發(fā)起連接請求的過程。之一步還是和服務(wù)端一樣,要建立一個套接字,方法和前面是一樣的。不一樣的是客戶端需要調(diào)用 connect 向服務(wù)端發(fā)起請求。
客戶端和服務(wù)器端的連接建立,是通過 connect 函數(shù)完成的。這是 connect 的構(gòu)建函數(shù):
函數(shù)的之一個參數(shù) sockfd 是連接套接字,通過前面講述的 socket 函數(shù)創(chuàng)建。
第二個、第三個參數(shù) servaddr 和 addrlen 分別代表指向套接字地址結(jié)構(gòu)的指針和該結(jié)構(gòu)的大小。套接字地址結(jié)構(gòu)必須含有服務(wù)器的 IP 地址和端口號。
客戶在調(diào)用函數(shù) connect 前不必非得調(diào)用 bind 函數(shù),因為如果需要的話,內(nèi)核會確定源 IP 地址,并按照一定的算法選擇一個臨時端口作為源端口。
如果是 TCP 套接字,那么調(diào)用 connect 函數(shù)將激發(fā) TCP 的三次握手過程,而且僅在連接建立成功或出錯時才返回。其中出錯返回可能有以下幾種情況:
1.三次握手無法建立,客戶端發(fā)出的 SYN 包沒有任何響應(yīng),于是返回 TIMEOUT 錯誤。這種情況比較常見的原因是對應(yīng)的服務(wù)端 IP 寫錯。
2.客戶端收到了 RST(復(fù)位)回答,這時候客戶端會立即返回 CONNECTION REFUSED 錯誤。這種情況比較常見于客戶端發(fā)送連接請求時的請求端口寫錯,因為 RST 是 TCP 在發(fā)生錯誤時發(fā)送的一種 TCP 分節(jié)。產(chǎn)生 RST 的三個條件是:
3.客戶發(fā)出的 SYN 包在網(wǎng)絡(luò)上引起了”destination unreachable”,即目的不可達(dá)的錯誤。這種情況比較常見的原因是客戶端和服務(wù)器端路由不通。
根據(jù)不同的返回值,我們可以做進(jìn)一步的排查。
我們先看一下最初的過程,服務(wù)器端通過 socket,bind 和 listen 完成了被動套接字的準(zhǔn)備工作,被動的意思就是等著別人來連接,然后調(diào)用 accept,就會阻塞在這里,等待客戶端的連接來臨;客戶端通過調(diào)用 socket 和 connect 函數(shù)之后,也會阻塞。接下來的事情是由操作系統(tǒng)內(nèi)核完成的,更具體一點的說,是操作系統(tǒng)內(nèi)核網(wǎng)絡(luò)協(xié)議棧在工作。
下面是具體的過程:
1.客戶端的協(xié)議棧向服務(wù)器端發(fā)送了 SYN 包,并告訴服務(wù)器端當(dāng)前發(fā)送序列號 j,客戶端進(jìn)入 SYNC_SENT 狀態(tài);
2.服務(wù)器端的協(xié)議棧收到這個包之后,和客戶端進(jìn)行 ACK 應(yīng)答,應(yīng)答的值為 j+1,表示對 SYN 包 j 的確認(rèn),同時服務(wù)器也發(fā)送一個 SYN 包,告訴客戶端當(dāng)前我的發(fā)送序列號為 k,服務(wù)器端進(jìn)入 SYNC_RCVD 狀態(tài);
3.客戶端協(xié)議棧收到 ACK 之后,使得應(yīng)用程序從 connect 調(diào)用返回,表示客戶端到服務(wù)器端的單向連接建立成功,客戶端的狀態(tài)為 ESTABLISHED,同時客戶端協(xié)議棧也會對服務(wù)器端的 SYN 包進(jìn)行應(yīng)答,應(yīng)答數(shù)據(jù)為 k+1;
4.應(yīng)答包到達(dá)服務(wù)器端后,服務(wù)器端協(xié)議棧使得 accept 阻塞調(diào)用返回,這個時候服務(wù)器端到客戶端的單向連接也建立成功,服務(wù)器端也進(jìn)入 ESTABLISHED 狀態(tài)。
這一講我們分別從服務(wù)端和客戶端的角度,講述了如何創(chuàng)建套接字,并利用套接字完成 TCP 連接的建立。
1.為什么是三次握手
1.信道不安全 保證通信需要一來一回
2.客戶端的來回和服務(wù)端的來回 共四次 這是最多四次
3.客戶端的回和服務(wù)端的來合并成一個,就是那個sync k ack j+1
4.這樣就是三次握手
這個問題的本質(zhì)是, 信道不可靠, 但是通信雙發(fā)需要就某個問題達(dá)成一致. 而要解決這個問題, 無論你在消息中包含什么信息, 三次通信是理論上的最小值. 所以三次握手不是TCP本身的要求, 而是為了滿足”在不可靠信道上可靠地傳輸信息”這一需求所導(dǎo)致的
關(guān)于linux tcp rst的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
分享名稱:深入了解LinuxTCPRST的作用和原因(linuxtcprst)
本文來源:http://www.5511xx.com/article/djjhgod.html


咨詢
建站咨詢
