1. 程式人生 > >TCP和HTTP學習筆記

TCP和HTTP學習筆記

TCP和HTTP的區別

TCP協議對應於傳輸層,而HTTP協議對應於應用層,從本質上來說,二者沒有可比性。Http協議是建立在TCP協議基礎之上的,當瀏覽器需要從伺服器獲取網頁資料的時候,會發出一次Http請求。Http會通過TCP建立起一個到伺服器的連線通道,當本次請求需要的資料完畢後,Http會立即將TCP連線斷開,這個過程是很短的。所以Http連線是一種短連線、無狀態的連線,TCP連線是一種長連線、有狀態的連線。所謂的無狀態,是指瀏覽器每次向伺服器發起請求的時候,不是通過一個連線,而是每次都建立一個新的連線。如果是一個連線的話,伺服器程序中就能保持住這個連線並且在記憶體中記住一些資訊狀態。而每次請求結束後,連線就關閉,相關的內容就釋放了,所以記不住任何狀態,成為無狀態連線。

TCP連線

當網路通訊時採用TCP協議時,在真正的讀寫操作之前,server與client之間必須建立一個連線,當讀寫操作完成後,雙方不再需要這個連線時它們可以釋放這個連線,連線的建立是需要三次握手的,而釋放則需要4次握手,所以說每個連線的建立都是需要資源消耗和時間消耗的。
TCP的三次握手
所謂三次握手(Three-Way Handshake)即建立TCP連線,就是指建立一個TCP連線時,需要客戶端和服務端總共傳送3個包以確認連線的建立
TCP的三次握手
第一次握手:客戶端將標誌位SYN置為1,隨機產生一個值seq=J,並將該資料包傳送給伺服器,客戶端進入SYN_SENT狀態,等待伺服器確認。
第二次握手:伺服器收到資料包後由標誌位SYN=1知道客戶端請求建立連線,伺服器將標誌位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,並將該資料包傳送給客戶端以確認連線請求,伺服器進入SYN_RCVD狀態
第三次握手:客戶端收到確認後,檢查ack是否為J+1,ACK是否為1,如果正確則將標誌位ACK置為1,ack=K+1,並將該資料包傳送給伺服器,客戶端檢查ack是否為K+1,ACK是否為1,如果正確則連線建立成功,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手

注意: 第三次握手是有可能失敗的,如果失敗的話,伺服器方面一直沒有等到ack,那麼會重新發送syn+ack給客戶端,請求成功並且受到ack包,那麼連線建立成功了;客戶端方面會考慮是否在一定時間內傳送了請求,如果傳送了請求,發現伺服器並沒有響應,發現了異常;如果沒有傳送請求,超過了一定時間,可以說並沒有建立連線
注意: SYN攻擊:
在三次握手過程中,Server傳送SYN-ACK之後,收到Client的ACK之前的TCP連線稱為半連線(half-open connect),此時Server處於SYN_RCVD狀態,當收到ACK後,Server轉入ESTABLISHED狀態。SYN攻擊就是Client在短時間內偽造大量不存在的IP地址,並向Server不斷地傳送SYN包,Server回覆確認包,並等待Client的確認,由於源地址是不存在的,因此,Server需要不斷重發直至超時,這些偽造的SYN包將產時間佔用未連線佇列,導致正常的SYN請求因為佇列滿而被丟棄,從而引起網路堵塞甚至系統癱瘓。SYN攻擊時一種典型的DDOS攻擊,檢測SYN攻擊的方式非常簡單,即當Server上有大量半連線狀態且源IP地址是隨機的,則可以斷定遭到SYN攻擊了,使用如下命令可以讓之現行:
#netstat -nap | grep SYN_RECV

tcp的四次揮手
所謂四次揮手(Four-Way Wavehand)即終止TCP連線,就是指斷開一個TCP連線時,需要客戶端和服務端總共傳送4個包以確認連線的斷開。在socket程式設計中,這一過程由客戶端或服務端任一方執行close來觸發
四次揮手
第一次揮手:客戶端主動關閉,傳送FIN,請求伺服器關閉連線,客戶端處於FIN_WAIT_1狀態
第二次揮手:伺服器收到FIN,傳送ack給客戶端,序列號為收到的FIN+1,伺服器姿勢處於CLOSE_WAIT狀態
第三次揮手:伺服器傳送FIN包,用來確認客戶端和伺服器的關閉,伺服器處於LAST_ACK狀態
第四次揮手:客戶端收到FIN包,處於TIME_WAIT,傳送ack給伺服器,序列號為收到的FIN+1,伺服器收到ack包後處於,變成CLOSED狀態,完成四次揮手

問:為什麼建立連線是三次握手,而斷開連線卻需要四次揮手?
因為伺服器處於listen狀態,當收到SYN報文的建連請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裡來發送。但關閉連線時,當收到對方的FIN報文通知時,它僅僅表示對方沒有資料傳送給你了;但未必你所有的資料都全部發送給對方了,所以你可以未必會馬上會關閉SOCKET,也即你可能還需要傳送一些資料給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連線了,所以它這裡的ACK報文和FIN報文多數情況下都是分開發送的

HTTP連線

短連線指建立SOCKET連線後傳送後接收完資料後馬上斷開連線,一般銀行都使用短連線解釋。
長連線就是指在基於tcp的通訊中,一直保持連線,不管當前是否傳送或者接收資料
短連線
在HTTP/1.0中,預設使用的是短連線,也就是說,瀏覽器和伺服器每進行一次HTTP操作,就建立一次連線,但任務結束就中斷連線。如果客戶端瀏覽器訪問的某個HTML或其他型別的 Web頁中包含有其他的Web資源,如JavaScript檔案、影象檔案、CSS檔案等;當瀏覽器每遇到這樣一個Web資源,就會建立一個HTTP會話。
長連線
因為隨著html的頁面複雜程度越來越大,短連線的http協議滿足不了現在的需求,所以在http/1.1,預設使用的是長連線,使用長連線的HTTP協議,會在響應頭有加入這行程式碼:

connect:keep-alive
keep-alive:timeout=20

在使用長連線的情況下,當一個網頁開啟完成後,客戶端和伺服器之間用於傳輸HTTP資料的 TCP連線不會關閉,如果客戶端再次訪問這個伺服器上的網頁,會繼續使用這一條已經建立的連線。Keep-Alive不會永久保持連線,它有一個保持時間,上述的timeout=20代表保持時間為20秒。實現長連線要客戶端和服務端都支援長連線
長輪詢
長輪詢就是http傳送一個請求,如果有資料就馬上響應,如果沒有就不響應;如果沒有響應的話,就會hold一段時間,等過了一段時間再繼續傳送http請求。
http 長輪詢的侷限:
瀏覽器端對統一伺服器同時 http 連線有最大限制, 最好同一使用者只存在一個長輪詢;
伺服器端沒有資料 hold 住連線時會造成浪費, 容易產生伺服器瓶頸
短輪詢
短輪詢就是http傳送一個請求,不管有沒有資料,都會馬上響應,然後hold一段時間之後,再重新發送http請求。
http 短輪詢的侷限是實時性低
兩者相同點:
可以看出 http 長輪詢和 http 短輪詢的都會 hold 一段時間;
兩者不同點
間隔發生在服務端還是瀏覽器端: http 長輪詢在服務端會 hold 一段時間, http 短輪詢在瀏覽器端 “hold” 一段時間;

總結

套用一段話來說就是,IP協議就相當於一條有路標的高速公路,而TCP/UDP協議就相當於公路上的大卡車,而http協議、file協議就想當與是卡車上的”貨物”。

參考地址: