TCP的三次握手編程
所謂三次握手(Three-way Handshake),是指創建一個TCP鏈接時,須要客戶端和服務器總共發送3個包。服務器
確認號ack:期待收到對方下一個報文段的第一個數據字節的序號。cookie
確認ACK:佔1位,僅當ACK=1時,確認號字段纔有效。ACK=0時,確認號無效。網絡
同步SYN:鏈接創建時用於同步序號。當SYN=1,ACK=0時表示:這是一個鏈接請求報文段。socket
若贊成鏈接,則在響應報文段中使得SYN=1,ACK=1。所以,SYN=1表示這是一個鏈接請求,或鏈接接受報文。tcp
終止FIN:用來釋放一個鏈接。FIN=1表示:此報文段的發送方的數據已經發送完畢,並要求釋放運輸鏈接。spa
第一次握手:
客戶端發送一個TCP的SYN標誌位置1的包指明客戶打算鏈接的服務器的端口,以及初始序號X,保存在包頭的序列號(Sequence Number)字段裏。blog
第二次握手:
服務器發回確認包(ACK)應答。即SYN標誌位和ACK標誌位均爲1同時,將確認序號(Acknowledgement Number)設置爲客戶的ISN加1以.即X+1。隊列
第三次握手:
客戶端再次發送確認包(ACK) SYN標誌位爲0,ACK標誌位爲1.而且把服務器發來ACK的序號字段+1,放在肯定字段中發送給對方.而且在數據段放寫ISN的+1進程
還要再發送一次確認是爲了,防止已失效的鏈接請求報文段忽然又傳到了B,於是產生錯誤。
已失效的報文段:正常狀況下:A發出鏈接請求,但由於丟失了,故而不能收到B的確認。因而A從新發出請求,而後收到確認,創建鏈接,數據傳輸完畢後,釋放鏈接,A發了2個,一個丟掉,一個到達,沒有「已失效的報文段」。
可是,某種狀況下,A的第一個在某個節點滯留了,延誤到達,原本這是一個早已失效的報文段,可是在A發送第二個,而且獲得B的迴應,創建了鏈接之後,這個報文段居然到達了,因而B就認爲,A又發送了一個新的請求,因而發送確認報文段,贊成創建鏈接,倘若沒有三次的握手,那麼這個鏈接就創建起來了(有一個請求和一個迴應),此時,A收到B的確認,但A知道本身並無發送創建鏈接的請求,由於不會理睬B的這個確認,因而呢,A也不會發送任何數據,而B呢卻覺得新的鏈接創建了起來,一直等待A發送數據給本身,此時B的資源就被白白浪費了。可是採用三次握手的話,A就不發送確認,那麼B因爲收不到確認,也就知道並無要求創建鏈接。
SYN攻擊
在三次握手過程當中,服務器發送SYN-ACK以後,收到客戶端的ACK以前的TCP鏈接稱爲半鏈接(half-open connect).此時服務器處於Syn_RECV狀態.當收到ACK後,服務器轉入ESTABLISHED狀態.
Syn攻擊就是 攻擊客戶端 在短期內僞造大量不存在的IP地址,向服務器不斷地發送syn包,服務器回覆確認包,並等待客戶的確認,因爲源地址是不存在的,服務器須要不斷的重發直 至超時,這些僞造的SYN包將長時間佔用未鏈接隊列,正常的SYN請求被丟棄,目標系統運行緩慢,嚴重者引發網絡堵塞甚至系統癱瘓。
Syn攻擊是一個典型的DDOS攻擊。檢測SYN攻擊很是的方便,當你在服務器上看到大量的半鏈接狀態時,特別是源IP地址是隨機的,基本上能夠判定這是一次SYN攻擊.在Linux下能夠以下命令檢測是否被Syn攻擊。
netstat -n -p TCP | grep SYN_RECV
通常較新的TCP/IP協議棧都對這一過程進行修正來防範Syn攻擊,修改tcp協議實現。主要方法有SynAttackProtect保護機制、SYN cookies技術、增長最大半鏈接和縮短超時時間等.可是不能徹底防範syn攻擊。
TCP的四次揮手
TCP的鏈接的拆除須要發送四個包,所以稱爲四次揮手(four-way handshake)。客戶端或服務器都可主動發起揮手動做,在socket編程中,任何一方執行close()操做便可產生揮手操做。
第一次揮手:TCP客戶端發送一個FIN,用來關閉客戶到服務器的數據傳送。
第二次揮手:服務器收到這個FIN,它發回一個ACK,確認序號爲收到的序號加1。和SYN同樣,一個FIN將佔用一個序號。
第三次揮手:服務器關閉客戶端的鏈接,發送一個FIN給客戶端。
第四次揮手:客戶段發回ACK報文確認,並將確認序號設置爲收到序號加1。
B收到鏈接釋放報文段後就當即發送確認,而後就進入close-wait狀態,此時TCP服務器進程就通知高層應用進程,於是從A到B的鏈接就釋放了。此時是「半關閉」狀態。即A不能夠發送給B,可是B能夠發送給A。
此時,若B沒有數據報要發送給A了,其應用進程就通知TCP釋放鏈接,而後發送給A鏈接釋放報文段,並等待確認。
A發送確認後,進入time-wait,注意,此時TCP鏈接尚未釋放掉,而後通過時間等待計時器設置的2MSL後,A才進入到close狀態。
爲何要等待呢?
①爲了保證A發送的最後一個ACK報文段可以到達B。即最後這個確認報文段頗有可能丟失,那麼B會超時重傳,而後A再一次確認,同時啓動2MSL計時器,如此下去。若是沒有等待時間,發送完確認報文段就當即釋放鏈接的話,B就沒法重傳了(鏈接已被釋放,任何數據都不能出傳了),於是也就收不到確認,就沒法按照步驟進入CLOSE狀態,即必須收到確認才能close。
②防止「已失效的鏈接請求報文段」出如今鏈接中。通過2MSL,那些在這個鏈接持續的時間內,產生的全部報文段就能夠都從網絡中消失。即在這個鏈接釋放的過程當中會有一些無效的報文段滯留在樓閣結點,可是呢,通過2MSL這些無效報文段就確定能夠發送到目的地,不會滯留在網絡中。這樣的話,在下一個鏈接中就不會出現上一個鏈接遺留下來的請求報文段了。