TCP(Transmission Control Protocol) 傳輸控制協議服務器
TCP是主機對主機層的傳輸控制協議,提供可靠的鏈接服務,採用三次握手確認創建一個鏈接:cookie
位碼即tcp標誌位,有6種標示:SYN(synchronous創建聯機) ACK(acknowledgement 確認) PSH(push傳送) FIN(finish結束) RST(reset重置) URG(urgent緊急)網絡
Sequence number(順序號碼) Acknowledge number(確認號碼)併發
下面詳細介紹幾個TCP標誌位:
tcp
ACK : TCP協議規定,只有ACK=1時有效,也規定鏈接創建後全部發送的報文的ACK必須爲1ide
SYN(SYNchronization) : 在鏈接創建時用來同步序號。當SYN=1而ACK=0時,代表這是一個鏈接請求報文。對方若贊成創建鏈接,則應在響應報文中使SYN=1和ACK=1. 所以, SYN置1就表示這是一個鏈接請求或鏈接接受報文。spa
FIN (finis):即完,終結的意思, 用來釋放一個鏈接。當 FIN = 1 時,代表此報文段的發送方的數據已經發送完畢,並要求釋放鏈接。3d
TCP創建鏈接:orm
首先Client端發送鏈接請求報文,Server段接受鏈接後回覆ACK報文,併爲此次鏈接分配資源。Client端接收到ACK報文後也向Server段發生ACK報文,並分配資源,這樣TCP鏈接就創建了。blog
注意:中斷鏈接端能夠是Client端,也能夠是Server端。
假設Client端發起中斷鏈接請求,也就是發送FIN報文。Server端接到FIN報文後,意思是說"我Client端沒有數據要發給你了",可是若是你還有數據沒有發送完成,則沒必要急着關閉Socket,能夠繼續發送數據。因此你先發送ACK,"告訴Client端,你的請求我收到了,可是我還沒準備好,請繼續你等個人消息"。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端肯定數據已發送完成,則向Client端發送FIN報文,"告訴Client端,好了,我這邊數據發完了,準備好關閉鏈接了"。Client端收到FIN報文後,"就知道能夠關閉鏈接了,可是他仍是不相信網絡,怕Server端不知道要關閉,因此發送ACK後進入TIME_WAIT狀態,若是Server端沒有收到ACK則能夠重傳。「,Server端收到ACK後,"就知道能夠斷開鏈接了"。Client端等待了2MSL後依然沒有收到回覆,則證實Server端已正常關閉,那好,我Client端也能夠關閉鏈接了。TCP鏈接就這樣關閉了!
注意: 在TIME_WAIT狀態中,若是TCP client端最後一次發送的ACK丟失了,它將從新發送。TIME_WAIT狀態中所須要的時間是依賴於實現方法的。典型的值爲30秒、1分鐘和2分鐘。等待以後鏈接正式關閉,而且全部的資源(包括端口號)都被釋放。
答疑時間:
爲何不能用兩次握手進行鏈接?
咱們知道,三次握手完成兩個重要的功能,既要雙方作好發送數據的準備工做(雙方都知道彼此已準備好),也要容許雙方就初始序列號進行協商,這個序列號在握手過程當中被髮送和確認。
如今把三次握手改爲僅須要兩次握手,死鎖是可能發生的。做爲例子,考慮計算機S和C之間的通訊,假定C給S發送一個鏈接請求分組,S收到了這個分組,併發 送了確認應答分組。按照兩次握手的協定,S認爲鏈接已經成功地創建了,能夠開始發送數據分組。但是,C在S的應答分組在傳輸中被丟失的狀況下,將不知道S 是否已準備好,不知道S創建什麼樣的序列號,C甚至懷疑S是否收到本身的鏈接請求分組。在這種狀況下,C認爲鏈接還未創建成功,將忽略S發來的任何數據分 組,只等待鏈接確認應答分組。而S在發出的分組超時後,重複發送一樣的分組。這樣就造成了死鎖。
關於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***。
爲何鏈接的時候是三次握手,關閉的時候倒是四次握手?
答:由於當Server端收到Client端的SYN鏈接請求報文後,能夠直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同 步的。可是關閉鏈接時,當Server端收到FIN報文時,極可能並不會當即關閉SOCKET,因此只能先回復一個ACK報文,告訴Client端,"你 發的FIN報文我收到了"。只有等到我Server端全部的報文都發送完了,我才能發送FIN報文,所以不能一塊兒發送。故須要四步握手。
爲何TIME_WAIT狀態須要通過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
答:雖然按道理,四個報文都發送完畢,咱們能夠直接進入CLOSE狀態了,可是咱們必須假象網絡是不可靠的,有能夠最後一個ACK丟失。因此TIME_WAIT狀態就是用來重發可能丟失的ACK報文。