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

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


咨詢
建站咨詢
