嵌入式學習筆記:TCP握(wo)手(shou)/揮(hui)手(shou)過程詳解
時間(jian):2018-09-10 來源:未知
很(hen)多人對TCP握(wo)手/揮手過程還是有一定的疑(yi)惑,這(zhe)個知識(shi)點(dian)可以說(shuo)是比(bi)較重要(yao)的,之(zhi)前我在面試(shi)過程中(zhong)還被問到過,所以這(zhe)是需要(yao)好(hao)好(hao)掌握(wo)的,而(er)且(qie)掌握(wo)好(hao)了(le),自己(ji)做一個這(zhe)方面的東西也是可以的,一起(qi)來看。
TCP連接建立(li)
在(zai)TCP/IP協(xie)議中,TCP協(xie)議提供(gong)可(ke)靠的(de)連接(jie)服務,采用三次握手建立一(yi)個連接(jie)。
服務器必(bi)須準(zhun)備好接受外來(lai)的連接。這通過調用socket、 bind和listen函數來(lai)完成,稱為被動打開(passive open)。
第一次握手:客(ke)戶(hu)通過調用(yong)connect進行主(zhu)動打(da)開(active open)。這引起客(ke)戶(hu)TCP發送一個(ge)SYN(表(biao)示同步)分(fen)節(SYN=J),它告(gao)訴服務器(qi)客(ke)戶(hu)將在連接(jie)中發送到數(shu)據的初(chu)始序列號。并進入(ru)SYN_SEND狀態(tai),等待(dai)服務器(qi)的確認(ren)。
第二次握手(shou):服務(wu)器必須確(que)認客戶(hu)(hu)的(de)SYN,同時(shi)自己(ji)也得(de)發送(song)一個SYN分節,它含有服務(wu)器將在(zai)同一連(lian)接中發送(song)的(de)數據的(de)初(chu)始序列號。服務(wu)器以單個字節向客戶(hu)(hu)發送(song)SYN和對客戶(hu)(hu)SYN的(de)ACK(表示確(que)認),此時(shi)服務(wu)器進入SYN_RECV狀(zhuang)態。
第三(san)次握(wo)手(shou):客戶收到服務(wu)(wu)器的(de)SYN+ACK。向服務(wu)(wu)器發送(song)確(que)認分(fen)節,此分(fen)節發送(song)完畢(bi),客戶服務(wu)(wu)器進(jin)入ESTABLISHED狀態,完成三(san)次握(wo)手(shou)。


圖1:TCP握手(shou)建(jian)立連接(jie)
客戶端的(de)(de)(de)(de)(de)初始序(xu)列(lie)號(hao)為(wei)(wei)(wei)J,而服務器的(de)(de)(de)(de)(de)初始序(xu)列(lie)號(hao)為(wei)(wei)(wei)K。在ACK里的(de)(de)(de)(de)(de)確認號(hao)為(wei)(wei)(wei)發(fa)送這個ACK的(de)(de)(de)(de)(de)一(yi)(yi)(yi)端所期待的(de)(de)(de)(de)(de)下一(yi)(yi)(yi)個序(xu)列(lie)號(hao)。因(yin)為(wei)(wei)(wei)SYN只(zhi)占一(yi)(yi)(yi)個字節的(de)(de)(de)(de)(de)序(xu)列(lie)號(hao)空間,所以每(mei)一(yi)(yi)(yi)個SYN的(de)(de)(de)(de)(de)ACK中的(de)(de)(de)(de)(de)確認號(hao)都是(shi)相應的(de)(de)(de)(de)(de)初始序(xu)列(lie)號(hao)加1.類(lei)似地,每(mei)一(yi)(yi)(yi)個FIN(表示結束)的(de)(de)(de)(de)(de)ACK中的(de)(de)(de)(de)(de)確認號(hao)為(wei)(wei)(wei)FIN的(de)(de)(de)(de)(de)序(xu)列(lie)號(hao)加1.
完成(cheng)三次握手,客戶端與(yu)服務器(qi)開始傳送數(shu)據,在上述過程中還有一些重(zhong)要概(gai)念。
未連接隊(dui)列:在三次握(wo)手協議中,服(fu)務器(qi)維護一個未連接隊(dui)列,該隊(dui)列為每個客戶端的SYN包(syn=j)開設(she)一個條(tiao)(tiao)(tiao)目(mu),該條(tiao)(tiao)(tiao)目(mu)表明服(fu)務器(qi)已(yi)收到SYN包,并向客戶發(fa)出確認,正在等待客戶端確認包。這些條(tiao)(tiao)(tiao)目(mu)所標識(shi)的連接在服(fu)務器(qi)處于SYN_RECV狀態(tai),當服(fu)務器(qi)收到客戶端確認包時(shi),刪除該條(tiao)(tiao)(tiao)目(mu),服(fu)務器(qi)進(jin)入ESTABLISHED狀態(tai)。


TCP連接終(zhong)止(zhi)
TCP連接(jie)終止需四個(ge)分節。


圖2:TCP揮手(shou)關閉(bi)連接
第一次握手(shou):某個應用進程首先(xian)調用close,我們稱這一端執(zhi)行主動關閉。這一端的TCP于是發(fa)送(song)一個FIN分節,表(biao)示數據發(fa)送(song)完畢(bi)。
第二次握手:接(jie)(jie)收到FIN的另一端(duan)執(zhi)行被動關(guan)閉(passive close)。這個FIN由TCP確認。它的接(jie)(jie)收也(ye)作為(wei)文件結束符傳(chuan)遞給(gei)接(jie)(jie)收端(duan)應用進(jin)程(cheng)(cheng)(放在已(yi)排隊等候應用進(jin)程(cheng)(cheng)接(jie)(jie)收到任何(he)其(qi)他數據之后)
第(di)三次(ci)握手(shou):一段時間后,接收(shou)到(dao)文件結束符的應用進程(cheng)將調用close關閉它(ta)的套接口。這(zhe)導致它(ta)的TCP也發送一個FIN。
第四(si)次握手:接收到這個FIN的原發送端TCP對(dui)它進行確(que)認。
面(mian)向字節(jie)(jie)的數據(ju)傳送流(liu)(如(ru)TCP字節(jie)(jie)流(liu)、Unix管道(dao)等)也使用(yong)EOF表(biao)示在某個方向上不再有(you)數據(ju)待傳送。在TCP字節(jie)(jie)流(liu)中,EOF的讀或寫通(tong)過收發一個特殊的FIN分節(jie)(jie)來(lai)實現。



