前言:
TCP協(xié)議是計(jì)算機(jī)的基礎(chǔ)相寇,他本身是一個非常非常復(fù)雜的協(xié)議声诸。
本文只是蜻蜓點(diǎn)水,將從網(wǎng)絡(luò)基礎(chǔ)以及TCP的相關(guān)概念介紹開始围苫,之后再將三次握手裤园,四次揮手這些內(nèi)容來闡述。
最后介紹一些常見問題剂府,并給出解答拧揽。
?網(wǎng)絡(luò)分層
在實(shí)際的網(wǎng)絡(luò)中,我們是四層網(wǎng)絡(luò)結(jié)構(gòu):
網(wǎng)絡(luò)傳輸層
網(wǎng)絡(luò)傳輸層負(fù)責(zé)最底層的底層鏈路連接。兩臺主機(jī)之間進(jìn)行互聯(lián)淤袜,基于網(wǎng)線的物理硬件上的協(xié)議万俗。在這個側(cè)面,主機(jī)與主機(jī)之間只認(rèn)得硬件mac編碼饮怯。并不認(rèn)識IP。
網(wǎng)絡(luò)層
IP就是在網(wǎng)絡(luò)層出現(xiàn)的嚎研,就像網(wǎng)絡(luò)上蓖墅,每個機(jī)器的地址。網(wǎng)絡(luò)層可以理解為快遞临扮,它的職能就是根據(jù)地址(IP)论矾,把東西從一個地方運(yùn)送到另一個地方
傳輸層
傳輸層相比于網(wǎng)絡(luò)層最大的不同就是引入了端口的概念。網(wǎng)絡(luò)層只管發(fā)送地址和目的地址杆勇。但是發(fā)送主機(jī)上有可能有多個程序和同一個接收主機(jī)進(jìn)行傳輸數(shù)據(jù)贪壳,怎么區(qū)分這多個程序呢?就引入了端口的概念蚜退。(發(fā)送IP地址闰靴,發(fā)送端口,接收IP地址钻注,接收端口)四元組標(biāo)示了一個主機(jī)的程序到另一個主機(jī)程序的唯一標(biāo)示蚂且。傳輸層的職能,就是維護(hù)這個四元組幅恋。
其實(shí)傳輸層還有一個職能是定義發(fā)送方和接收方基本處理包的行為杏死。上面說到網(wǎng)絡(luò)層就相當(dāng)于郵件運(yùn)輸工,它只負(fù)責(zé)把一包東西從一個地方放到另外一個地方捆交,但是淑翼,這包東西是否送達(dá)了,送達(dá)之后接收方又有什么行為品追。這些都可以在傳輸層進(jìn)行定義玄括。注意,這里說的是可以诵盼,你也可以在傳輸層布不管這些惠豺,只做簡單的基本封裝四元組,比如UDP
應(yīng)用層
指定到主機(jī)端口了风宁,接下來就是應(yīng)用層干活了洁墙,可以傳文件,傳文本戒财。應(yīng)用層就是實(shí)際上對具體的程序之間的交互功能進(jìn)行定義的層热监。
TCP協(xié)議
TCP(Transmission Control Protocol) 傳輸控制協(xié)議.TCP是主機(jī)對主機(jī)層的傳輸控制協(xié)議,提供可靠的連接服務(wù)饮寞,采用三次握手確認(rèn)建立一個連接孝扛。
協(xié)議結(jié)構(gòu)如下:
這里就不全部都講了列吼,主介紹一部分:
Source Port和Destination Port
這兩個字段表示發(fā)送地址和目的地址的端口號,發(fā)送地址的IP和目的地址的IP是在IP協(xié)議頭中
Sequence number(順序號碼) Acknowledge number(確認(rèn)號碼)
TCP的任意一端(不管是客戶端還是服務(wù)端)苦始,可以發(fā)送數(shù)據(jù)寞钥,也可以接受數(shù)據(jù)。那么發(fā)送序列號就是Seqence Number陌选,接受序列號就是Acknowledgement Number理郑。
其次,序列號是用來標(biāo)志包的順序的咨油。網(wǎng)絡(luò)中包由于網(wǎng)絡(luò)問題您炉,接受到的并不是按順序到達(dá)的,接受端可以根據(jù)這個序列號來進(jìn)行組裝役电。
比如:
給服務(wù)端發(fā)送8000字節(jié)的數(shù)據(jù)赚爵,順序號從10000開始,分成4個包發(fā)送法瑟,那么它們的標(biāo)識就是12000,14000,16000,18000冀膝。
如下圖所示,由于網(wǎng)絡(luò)問題霎挟,最先到達(dá)的是序號為14000畸写,但是服務(wù)端可以根據(jù)這些包的序號進(jìn)行拼接,拼成完整的包氓扛。
Data offset和Reserved
由于tcp頭可能是不固定大小的(因?yàn)榇嬖诳蛇x字段)枯芬,所以需要有這個值來表示當(dāng)前這個包的tcp頭有多大。
Reserved就是保留字段
位碼TCP標(biāo)志位
就是下圖中的紅框的內(nèi)容
SYN(synchronous建立聯(lián)機(jī)):建立連接采郎,發(fā)送一方告知另外一方千所,請求建立連接
ACK(acknowledgement 確認(rèn)):該包中有回復(fù)信息
PSH(push傳送):該包中有傳輸信息
FIN(finish結(jié)束):結(jié)束位,發(fā)送一方告知另外一方蒜埋,請求中斷連接
RST(reset重置):重置位淫痰,這個包是用來要對方重置連接
URG(urgent緊急):緊急位,已經(jīng)建議棄用
?
握手與揮手:
?有了上面的基礎(chǔ)知識整份,相信下面的三次揮手和四次握手理解起來也不會費(fèi)勁的待错。
下圖是三次握手的過程:
三次握手過程說明:
TCP服務(wù)器進(jìn)程先創(chuàng)建傳輸控制塊TCB(存儲了每一個連接中的一些重要信息,如:TCP連接表烈评,到發(fā)送和接收緩存的指針火俄,到重傳隊(duì)列的指針,當(dāng)前的發(fā)送和接收序號讲冠,等)瓜客,準(zhǔn)備接受客戶進(jìn)程的連接請求。然后服務(wù)器進(jìn)程就處于LISTEN(收聽)狀態(tài),等待客戶的連接請求谱仪。如有玻熙,即作出相應(yīng)。
第一次握手:
客戶端Client向服務(wù)端Server發(fā)起建立連接請求疯攒∴滤妫客戶端會發(fā)送位碼SYN(請求建立連接),以及序列號x(seq=x)敬尺,TCP規(guī)定称杨,SYN報(bào)文段(即SYN=1的報(bào)文段)不能攜帶數(shù)據(jù),但要消耗掉一個序號筷转。這時,TCP客戶進(jìn)程進(jìn)入SYN-SENT(同步已發(fā)送)狀態(tài)悬而。
第二次握手:
服務(wù)端Server接受到請求報(bào)文段之后呜舒。如同意建立連接,則向客戶端發(fā)送確認(rèn)消息笨奠。在確認(rèn)報(bào)文段中應(yīng)把SYN位和ACK位都置1袭蝗,確認(rèn)號是ack=x+1,同時也為自己選擇一個初始序號seq=y般婆。注意到腥。這個報(bào)文段也不能攜帶數(shù)據(jù),但同樣要消耗掉一個序號蔚袍。這時服務(wù)端進(jìn)程進(jìn)入SYN-RCVD(同步收到)狀態(tài)乡范。
第三次握手:
客戶端Client收到服務(wù)端Server的確認(rèn)后,還要向服務(wù)端給出確認(rèn)啤咽。確認(rèn)報(bào)文段的ACK置1晋辆,確認(rèn)號ack=y+1,而自己的序號seq=x+1宇整。這時瓶佳,TCP連接已經(jīng)建立,客戶端進(jìn)入ESTABLISHED(已連接狀態(tài))鳞青。當(dāng)服務(wù)端收到客戶端的確認(rèn)之后,也進(jìn)入ESTABLISHED狀態(tài)。
總結(jié):
客戶端在三次握手中慌核,狀態(tài)的轉(zhuǎn)變是:CLOSED->SYN_SEND->ESTABLISHED
服務(wù)端在三次握手中押逼,狀態(tài)的轉(zhuǎn)變是:CLOSED->LISTENED->SYN_RCVD->ESTABLISHED
問題一:為什么不可以兩次握手,為什么客戶端還要再發(fā)送一次確認(rèn)胶惰?
答:消除舊有連接請求的SYN消息對新連接的干擾器仗,同步連接雙方的序列號和確認(rèn)號并交換TCP 窗口大小信息。
比如說這種異常情況:客戶端發(fā)出的第一個連接請求報(bào)文段并沒有丟失,而是在某些網(wǎng)絡(luò)結(jié)點(diǎn)長時間滯留了精钮,以致延誤到連接釋放以后的某個時間才到達(dá)服務(wù)端威鹿。本來這是一個早已失效的報(bào)文段。但服務(wù)端收到此失效的連接請求報(bào)文段后轨香,就誤以為是客戶端又發(fā)出一次新的連接請求忽你。于是就向客戶端發(fā)出確認(rèn)報(bào)文段,同意建立連接臂容。假定不采用三次握手科雳,那么只要服務(wù)端發(fā)出確認(rèn),新的連接就建立了脓杉。
問題二:什么是SYN攻擊糟秘?如何檢測它?
?? 在三次握手過程中球散,服務(wù)器發(fā)送SYN-ACK之后尿赚,收到客戶端的ACK之前的TCP連接稱為半連接(half-open connect).此時服務(wù)器處于Syn_RECV狀態(tài).當(dāng)收到ACK后,服務(wù)器轉(zhuǎn)入ESTABLISHED狀態(tài).
Syn攻擊就是 攻擊客戶端
在短時間內(nèi)偽造大量不存在的IP地址蕉堰,向服務(wù)器不斷地發(fā)送syn包凌净,服務(wù)器回復(fù)確認(rèn)包,并等待客戶的確認(rèn)屋讶,由于源地址是不存在的冰寻,服務(wù)器需要不斷的重發(fā)直
至超時,這些偽造的SYN包將長時間占用未連接隊(duì)列皿渗,正常的SYN請求被丟棄斩芭,目標(biāo)系統(tǒng)運(yùn)行緩慢,嚴(yán)重者引起網(wǎng)絡(luò)堵塞甚至系統(tǒng)癱瘓乐疆。
? Syn攻擊是一個典型的DDOS攻擊秒旋。檢測SYN攻擊非常的方便,當(dāng)你在服務(wù)器上看到大量的半連接狀態(tài)時诀拭,特別是源IP地址是隨機(jī)的迁筛,基本上可以斷定這是一次SYN攻擊.在Linux下可以如下命令檢測是否被Syn攻擊:
netstat -n -p TCP | grep SYN_RECV
一般較新的TCP/IP協(xié)議棧都對這一過程進(jìn)行修正來防范Syn攻擊,修改tcp協(xié)議實(shí)現(xiàn)耕挨。主要方法有SynAttackProtect保護(hù)機(jī)制细卧、SYN cookies技術(shù)、增加最大半連接和縮短超時時間等.
但是不能完全防范syn攻擊筒占。
四次揮手過程說明:
?在客戶端和服務(wù)端已經(jīng)建立連接的情況下贪庙,需要四次揮手來斷開連接。如下圖所示:
第一次揮手:
客戶端發(fā)送一個FIN=1的報(bào)文段和順序號為u(seq=u)的請求關(guān)閉消息(客戶端沒有消息要發(fā)給你了翰苫,我準(zhǔn)備關(guān)閉連接了止邮,但是如果你還有數(shù)據(jù)沒有發(fā)送完成这橙,則不必急著關(guān)閉Socket,可以繼續(xù)發(fā)送數(shù)據(jù)导披。所以你先發(fā)送ACK)屈扎。客戶端進(jìn)入FIN-WAIT-1狀態(tài)撩匕,等待服務(wù)端的FIN報(bào)文段鹰晨。
第二次揮手:
服務(wù)端收到客戶端的FIN報(bào)文段,會發(fā)送一個確認(rèn)報(bào)文段ACK=1止毕,以及確認(rèn)序列號ack=u+1模蜡,還有自己的序列號seq=v(告訴客戶端,我已經(jīng)收到你的請求關(guān)閉消息扁凛,但是我還沒準(zhǔn)備好忍疾,請繼續(xù)等待),服務(wù)單進(jìn)入CLOSE-WAIT階段谨朝,此時服務(wù)端還未關(guān)閉卤妒。
第三次揮手:
服務(wù)端向客戶端發(fā)送FIN=1報(bào)文段(告訴Client端,好了叠必,我這邊數(shù)據(jù)發(fā)完了,準(zhǔn)備好關(guān)閉連接了)妹窖,ACK=1,序列號seq=w纬朝,ack=u+1,服務(wù)端進(jìn)入LAST-ACK狀態(tài)
第四次揮手:
客戶端收到服務(wù)端發(fā)來的FIN=1報(bào)文段骄呼,給服務(wù)端發(fā)送ACK=1報(bào)文段共苛,序列號seq=u+1,ack=w+1的消息蜓萄。這時客戶端就可以關(guān)閉連接了隅茎,但是他還是不相信網(wǎng)絡(luò),怕Server端不知道要關(guān)閉嫉沽,所以發(fā)送ACK后進(jìn)入TIME_WAIT狀態(tài)辟犀,如果Server端沒有收到ACK則可以重傳
,客戶端等待了2MSL后依然沒有收到回復(fù)绸硕,客戶端關(guān)閉堂竟。服務(wù)端也關(guān)閉。
總結(jié):
客戶端在四次揮手中的狀態(tài)變化是:ESTABLISHED -> FIN-WAITED-1 -> FIN-WAITED-2 -> TIME-WAITED -> CLOSED
服務(wù)單在四次揮手中的狀態(tài)變化是:ESTABLISHED -> CLOSE-WAITED LAST-ACK -> CLOSED
?
問題一:為什么在第四次回收后會有2個MSL的延時玻佩?
首先了解MSL出嘹,Maximum Segment Lifetime,最大報(bào)文生存時間,2個MSL是報(bào)文段發(fā)送和接受的最長時間咬崔。
假定網(wǎng)絡(luò)不可靠税稼,那么第四次發(fā)送的ACK可能丟失烦秩,即服務(wù)端無法收到這個ACK,如果服務(wù)端收不到這個確認(rèn)ACK郎仆,服務(wù)端會定時向客戶端端重復(fù)發(fā)送FIN只祠,直到服務(wù)單端收到客戶端的確認(rèn)ACK。所以這個2MSL就是用來處理這個可能丟失的ACK的丸升。
問題二:為什么握手只要三次铆农,揮手卻需要四次?
在TCP連接中狡耻,服務(wù)端SYN和ACK向客戶端發(fā)送是一次性發(fā)送的墩剖,而在斷開連接的過程中,服務(wù)端向客戶端發(fā)送的ACK和FIN是分兩次發(fā)送的夷狰。因?yàn)樵诜?wù)端接受到客戶端的FIN后岭皂,服務(wù)端還有數(shù)據(jù)要傳輸?shù)脑挘韵劝l(fā)送ACK沼头,等服務(wù)端處理完自己的事情后就可以發(fā)送FIN斷開連接了爷绘。
下篇預(yù)告:
TCP長連接與短連接,與Socket的聯(lián)系
參考鏈接: