11. 四次揮手中的TIME_WAIT狀態(tài)?
首先要明確一點(diǎn):主動(dòng)關(guān)閉連接的一方,才會(huì)有TIME_WAIT狀態(tài)。
之所以需要TIME_WAIT狀態(tài),主要是兩個(gè)原因:
防止相同的端口重新連接時(shí),服務(wù)器收到的是停留在網(wǎng)絡(luò)間的數(shù)據(jù)包
保證被動(dòng)關(guān)閉連接的一方能被正確的關(guān)閉,即保證最后的 ACK 能讓被動(dòng)關(guān)閉方接收,從而幫助其正常關(guān)閉
12. 為什么TIME_WAIT時(shí)間為2MSL?
MSL 是 Maximum Segment Lifetime,報(bào)文最大生存時(shí)間,它是任何報(bào)文在網(wǎng)絡(luò)上存在的最長(zhǎng)時(shí)間,超過這個(gè)時(shí)間報(bào)文將被丟棄。比如如果被動(dòng)關(guān)閉方?jīng)]有收到斷開連接的最后的 ACK 報(bào)文,就會(huì)觸發(fā)超時(shí)重發(fā) FIN 報(bào)文,另一方接收到 FIN 后,會(huì)重發(fā) ACK 給被動(dòng)關(guān)閉方,一來一去正好 2 個(gè) MSL。
2MSL 的時(shí)間是從客戶端接收到 FIN 后發(fā)送 ACK 開始計(jì)時(shí)的。如果在 TIME-WAIT 時(shí)間內(nèi),因?yàn)榭蛻舳说?ACK 沒有傳輸?shù)椒⻊?wù)端,客戶端又接收到了服務(wù)端重發(fā)的 FIN 報(bào)文,那么 2MSL 時(shí)間將重新計(jì)時(shí)。在Linux系統(tǒng)中,2MSL默認(rèn)值是60秒。
13. 什么是TCP的保活機(jī)制?
定義一個(gè)時(shí)間段,在這個(gè)時(shí)間段內(nèi),如果沒有任何連接相關(guān)的活動(dòng),TCP保活機(jī)制會(huì)開始作用,每隔一個(gè)時(shí)間間隔,發(fā)送一個(gè)探測(cè)報(bào)文,該探測(cè)報(bào)文包含的數(shù)據(jù)非常少,如果連續(xù)幾個(gè)探測(cè)報(bào)文都沒有得到響應(yīng),則認(rèn)為當(dāng)前的TCP 連接已經(jīng)死亡,系統(tǒng)內(nèi)核將錯(cuò)誤信息通知給上層應(yīng)用程序。
14. 已經(jīng)建立連接,客戶端故障怎么辦?
這種情況就會(huì)觸發(fā)TCP的;顧C(jī)制,對(duì)應(yīng)的參數(shù)包括;顣r(shí)間、;钐綔y(cè)的次數(shù)、;钐綔y(cè)的時(shí)間間隔,其中;顣r(shí)間默認(rèn)為7200秒,;钐綔y(cè)次數(shù)為9,;钐綔y(cè)時(shí)間間隔為75秒。
也就意味著,如果客戶端突然故障,會(huì)經(jīng)過7200+75*9=7875秒即2小時(shí)11分15后,服務(wù)器才會(huì)判斷該連接失效,以上參數(shù)可以手動(dòng)設(shè)置。
15. TCP/IP協(xié)議與Socket之間是什么關(guān)系?
網(wǎng)絡(luò)有一段關(guān)于Socket和TCP/IP協(xié)議關(guān)系的說法比較容易理解:
TCP/IP只是一個(gè)協(xié)議棧,就像操作系統(tǒng)的運(yùn)行機(jī)制一樣,必須要具體實(shí)現(xiàn),同時(shí)還要提供對(duì)外的操作接口。這個(gè)就像操作系統(tǒng)會(huì)提供標(biāo)準(zhǔn)的編程接口,比如Win32編程接口一樣,TCP/IP也要提供可供程序員做網(wǎng)絡(luò)開發(fā)所用的接口,這就是Socket編程接口。
所以,Socket跟TCP/IP并沒有必然的聯(lián)系,Socket編程接口在設(shè)計(jì)的時(shí)候,就希望能適應(yīng)其他的網(wǎng)絡(luò)協(xié)議。Socket的出現(xiàn)只是可以更方便的使用TCP/IP協(xié)議棧而已,其對(duì)TCP/IP進(jìn)行了抽象,形成了一些最基本的函數(shù)接口,比如Send,Listen等。
16. 什么是SYN攻擊?
我們都知道 TCP 連接建立是需要三次握手,假設(shè)攻擊者短時(shí)間偽造不同 IP 地址的 SYN 報(bào)文,服務(wù)端每接收到一個(gè)SVN 報(bào)文,就進(jìn)入SYN_RCVD 狀態(tài),但服務(wù)端發(fā)送出去的 ACK + SYN 報(bào)文,無法得到未知IP 主機(jī)的 ACK 應(yīng)答,久而久之就會(huì)占滿服務(wù)端的 SYN 接收隊(duì)列(未連接隊(duì)列),使得服務(wù)器不能為正常用戶服務(wù)。
17. 如何避免SYN攻擊?
避免SYN攻擊的兩個(gè)方案:
通過修改內(nèi)核參數(shù),控制隊(duì)列大小,并確定好當(dāng)隊(duì)列滿之后應(yīng)該如何處理,比如隊(duì)列滿之后,對(duì)新的SYN直接回復(fù)RST,丟棄連接。
當(dāng)SYN隊(duì)列滿了之后,后續(xù)收到的SYN,不直接進(jìn)入SYN隊(duì)列,而是先計(jì)算Cookie值,再發(fā)送,后續(xù)可以驗(yàn)證ACK包的合法性
18. TCP服務(wù)器Socket編程流程
服務(wù)端初始化 Socket,得到文件描述符
服務(wù)端調(diào)用 Bind,將綁定在 IP 地址和端口
服務(wù)端調(diào)用 Listen,進(jìn)行監(jiān)聽
服務(wù)端調(diào)用 Accept,建立客戶端連接
通過Send向客戶端發(fā)送消息
通過Receive接收客戶端消息
19. TCP客戶端Socket編程?
客戶端初始化 Socket,得到文件描述符
客戶端調(diào)用Connect,連接服務(wù)器
連接成功調(diào)用Send向客戶端發(fā)送消息
通過Receive接收客戶端消息
20. Listen中的backlog參數(shù)什么意義?
Linux內(nèi)核中會(huì)維護(hù)兩個(gè)隊(duì)列:
未完成連接隊(duì)列(SYN 隊(duì)列):接收到一個(gè) SYN 建立連接請(qǐng)求,處于 SYN_RCVD 狀態(tài); 已完成連接隊(duì)列(Accpet 隊(duì)列):已完成 TCP 三次握手過程,處于 ESTABLISHED 狀態(tài);
在內(nèi)核 2.2 之后,backlog 變成 Accept 隊(duì)列,也就是已完成連接建立的隊(duì)列長(zhǎng)度,所以現(xiàn)在通常認(rèn)為 backlog 是 Accept 隊(duì)列。