TCP 實(shí)際應(yīng)用

淺談 TCP 介紹了 TCP 基礎(chǔ)的理論知識(shí),這篇主要介紹 TCP 的一些應(yīng)用場(chǎng)景,主要包括(SYN Flood,TCP 長(zhǎng)連接和短連接,TCP/IP 實(shí)現(xiàn))。

1. SYN Flood

SYN Flood 又稱 SYN 洪水,是利用 TCP 三次握手的漏洞產(chǎn)生的一種攻擊方式。
常用攻擊方式有兩種,最終結(jié)果都是造成服務(wù)端在等待 ACK。一種是客戶端只管發(fā)出 SYN,不理會(huì)服務(wù)端返回的 ACK。一種是客戶端構(gòu)造錯(cuò)誤的來(lái)源 IP,使服務(wù)端返回 ACK 到錯(cuò)誤 IP。這兩種情況都會(huì)導(dǎo)致服務(wù)端無(wú)法正常收到客戶端發(fā)來(lái)的 ACK。使得 TCP 連接保持在半打開(kāi)狀態(tài),當(dāng) SYN 請(qǐng)求量過(guò)大時(shí),會(huì)出現(xiàn)大量半打開(kāi)狀態(tài)的 TCP 連接,當(dāng)系統(tǒng)資源被消耗盡后,導(dǎo)致新的連接無(wú)法被創(chuàng)建,造成正常用戶無(wú)法訪問(wèn)。

2. TCP 長(zhǎng)連接/TCP 短連接

首先需要知道的是 TCP 連接建立需要三次握手,斷開(kāi)連接需要四次,所以每次 TCP 的建立和關(guān)閉是需要消耗資源的。
TCP 短連接就是請(qǐng)求完成后關(guān)閉連接(一般是客戶端主動(dòng)關(guān)閉)。
TCP 長(zhǎng)連接是請(qǐng)求完成后仍保持 TCP 連接的狀態(tài),可繼續(xù)傳輸數(shù)據(jù)。TCP ?;罟δ懿捎枚〞r(shí)器來(lái)檢測(cè)連接狀態(tài)??蛻舳丝赡苷_\(yùn)行,已經(jīng)崩潰,重啟或不可達(dá),服務(wù)端需要針對(duì)檢測(cè)的情況做出不同反應(yīng)。

2.1 優(yōu)缺點(diǎn):

短連接管理簡(jiǎn)單,存在的連接都是最近建立和使用的。但每次建立和關(guān)閉新連接會(huì)有資源消耗,當(dāng)在大并發(fā)請(qǐng)求場(chǎng)景中使用,會(huì)出現(xiàn)大量的 TIME_WAIT 狀態(tài)的連接。導(dǎo)致資源的較大消耗。
長(zhǎng)連接需要 TCP ?;疃〞r(shí)器來(lái)檢測(cè)連接狀態(tài)。同時(shí)需要考慮不同長(zhǎng)連接的負(fù)載均衡問(wèn)題,但是可以在客戶端通過(guò)連接池得到部分解決,但在不同客戶端之間的負(fù)載均衡就無(wú)法做到。另外因?yàn)殚L(zhǎng)連接存在只創(chuàng)建不關(guān)閉的情況,所以會(huì)導(dǎo)致建立的長(zhǎng)連接越來(lái)越多。

2.2 短連接在請(qǐng)求量較大時(shí),導(dǎo)致過(guò)多的 TIME_WAIT

參考 淺談 TCP 1.3 中的圖,因?yàn)?TCP 是雙工模式,所以每個(gè)方向的連接都需要單獨(dú)關(guān)閉。
主動(dòng)關(guān)閉的一方發(fā)送 FIN 后,收到被動(dòng)關(guān)閉一方的 FIN,隨后返回 ACK 信號(hào),被動(dòng)關(guān)閉一方完成關(guān)閉連接閉環(huán),到達(dá) CLOSED 狀態(tài)。
而主動(dòng)關(guān)閉一方收到 FIN 后,發(fā)出 ACK,揮手已經(jīng)結(jié)束,所以主動(dòng)關(guān)閉一方不清楚被動(dòng)關(guān)閉一方收到 ACK 沒(méi)有,所以只能等待超出 2MSL(Maximum Segment Lifetime 報(bào)文段最大生存時(shí)間)后,如沒(méi)有再次收到 FIN (重連)即可進(jìn)行關(guān)閉。
2MSL 是因?yàn)楸粍?dòng)關(guān)閉一方首先等待 MSL 如果沒(méi)收到 ACK 則重新發(fā)送 FIN,然后主動(dòng)關(guān)閉一方等待 MSL 看是否能收到被動(dòng)關(guān)閉一方重新發(fā)送的 FIN,如果沒(méi)有收到則表示被動(dòng)關(guān)閉一方已成功收到了 ACK。

3. RPC 接口過(guò)度擔(dān)心性能

例如提供:get_topic_token_by_id 還是 get_topic_by_id?
當(dāng)數(shù)據(jù)傳輸長(zhǎng)度小于 MSS,數(shù)據(jù)仍被封裝在一個(gè)數(shù)據(jù)包中進(jìn)行傳輸,所以不會(huì)導(dǎo)致性能的下降。

4. Socket 剖析

4.1 基礎(chǔ) API

socket():創(chuàng)建一個(gè) socket 描述符(socket descriptor)。
bind():將一個(gè)地址族中的特定地址與 socket 進(jìn)行綁定。
listen():服務(wù)器通過(guò) listen 來(lái)監(jiān)聽(tīng)請(qǐng)求。
connect():客戶端通過(guò) connect 發(fā)出連接請(qǐng)求。
accept():內(nèi)核生成一個(gè)全新的描述符,代表與客戶唯一的 TCP 連接。
read()/write():從文件描述符中讀取數(shù)據(jù)或?qū)懭霐?shù)據(jù)到文件描述符。
close():關(guān)閉 socket 描述符(TODO:accept() 和 socket() 創(chuàng)建的描述符都需要關(guān)閉嗎?)

4.2 blocking 和 non-blocking 區(qū)別?

在 Network IO 操作中會(huì)涉及到兩種系統(tǒng)對(duì)象,一個(gè)是調(diào)用這個(gè) IO 用戶進(jìn)程(user process),一個(gè)是系統(tǒng)內(nèi)核(kernel)。

4.2.1 寫(xiě)阻塞:

當(dāng)調(diào)用 write 操作時(shí),只是將要寫(xiě)的數(shù)據(jù)復(fù)制到 kernel 的發(fā)送緩沖區(qū),什么時(shí)候發(fā)送到網(wǎng)絡(luò),什么時(shí)候?qū)Ψ浇邮?,系統(tǒng)不進(jìn)行通知和保證。所以當(dāng) kernel 的 send buffer 滿了之后就會(huì)造成 write 阻塞,即寫(xiě)入的速度大于對(duì)方讀取的速度。

4.2.2 讀阻塞:

當(dāng)調(diào)用 read 操作時(shí),會(huì)首先檢查 kernel 的 receive buffer 中是否有數(shù)據(jù),如果有數(shù)據(jù)則將數(shù)據(jù)拷貝到用戶進(jìn)程中,如果沒(méi)有數(shù)據(jù),blocking 和 non-blocking 進(jìn)行會(huì)做出不同的反應(yīng)。

4.2.3 blocking vs non-blocking

blocking IO 發(fā)現(xiàn) kernel 中無(wú)數(shù)據(jù),會(huì)進(jìn)行等待直到有數(shù)據(jù)出現(xiàn),然后再將數(shù)據(jù)從 kernel 拷貝到用戶進(jìn)程。
non-blocking IO 發(fā)現(xiàn) kernel 中無(wú)數(shù)據(jù)會(huì)直接返回 error。從用戶角度,進(jìn)程不再需要等待,每次 read 操作都會(huì)得到一個(gè)結(jié)果。當(dāng)進(jìn)程發(fā)現(xiàn) read 返回 error 后可以再次進(jìn)行 read 操作。
關(guān)于 blocking IO/non-blocking IO 的詳細(xì)細(xì)節(jié)可以參考:IO - 同步,異步,阻塞,非阻塞 (亡羊補(bǔ)牢篇)

疑問(wèn):(TODO)
長(zhǎng)連接導(dǎo)致報(bào)錯(cuò)的原因?(TCP keepalive)
當(dāng) TCP 數(shù)據(jù)包被 socket 隔斷后如何重新組裝?(eg: return big_data)
當(dāng) Socket 讀寫(xiě)發(fā)生錯(cuò)誤時(shí),如何進(jìn)行數(shù)據(jù)重傳?

參考資料:

SYN flood - 維基百科
TCP的 TIME_WAIT 快速回收與重用
Socket 通信原理和實(shí)現(xiàn)
IO - 同步,異步,阻塞,非阻塞 (亡羊補(bǔ)牢篇)
TCP/IP 應(yīng)用程序的通信連接模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)、netstat -nat 查看TCP各個(gè)狀態(tài)的數(shù)量2)、lso...
    北辰青閱讀 9,708評(píng)論 0 11
  • 18.1 引言 TCP是一個(gè)面向連接的協(xié)議。無(wú)論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一條連接。本章將...
    張芳濤閱讀 3,526評(píng)論 0 13
  • 最近在惡補(bǔ)計(jì)算機(jī)網(wǎng)絡(luò)方面的知識(shí),之前對(duì)于TCP的三次握手和四次分手也是模模糊糊,對(duì)于其中的細(xì)節(jié)更是渾然不知,最近看...
    微醺歲月閱讀 9,662評(píng)論 4 128
  • 1.這篇文章不是本人原創(chuàng)的,只是個(gè)人為了對(duì)這部分知識(shí)做一個(gè)整理和系統(tǒng)的輸出而編輯成的,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,353評(píng)論 6 174
  • 愛(ài),真的讓人好難受,是么?但是,沒(méi)有經(jīng)歷怎么成長(zhǎng)友情、
    張妍辰閱讀 201評(píng)論 0 0

友情鏈接更多精彩內(nèi)容