咱們都學過TCP,HTTP的相關概念,本文藉助協議分析工具Wireshark,讓你們對一些概念眼見爲實,權當溫故而知新。html
場景:web
在Client(10.239.196.211)上經過web browser訪問另外一臺Server(10.239.9.22)上的web server. express
步驟:瀏覽器
0. 首先配置Wireshark -> Edit -> Preference -> Protocol: ide
以下配置的HTTP包顯示效果與TCP segment的時序比較一致,便於理解。工具
1. 用瀏覽器訪問 http://10.239.9.22:8080/,同時打開Wireshark, 抓包以下:spa
2. 抓到的內容太多,先用Wireshark filter expression過濾一下: http 3d
3. 而後咱們找到了關心的packet, 右鍵 Follow -> TCP Stream,找到所在的TCP Stream code
因而獲得了以下比較清爽的結果,呈現的便是"HTTP請求所用到的那個TCP connection"(在HTTP 1.1的實現中,同一個TCP Connection能夠被多個HTTP通訊複用。)server
4. 一些分析
HTTP 層把下層的TCP的PDU (也就是TCP segment)從新組裝成本身的PDU(也就是HTTP message)。在各個協議層,有不一樣的PDU,每一個協議層要作2件事情:(i)把本身待發送的PDU交給下層去發送 (ii)把下層的收到PDU拿過來組裝成本身的PDU。
TCP只負責發送本身的PDU,也就是TCP segment,TCP會把收到的數據放到本身的buffer裏,那麼什麼時候這些數據會傳送給上層的HTTP呢?或者換句話說,HTTP如何知道該用哪些 TCP segment來拼成一個HTTP message呢?這就是PSH flag的做用。觀察下圖,咱們會看到PSH flag老是出如今一個TCP傳輸最後一部分的HTTP message時。
關於PSH的權威解釋,能夠看這個帖子:https://ask.wireshark.org/questions/20423/pshack-wireshark-capture
引用以下:
PSH is an indication by the sender that, if the receiving machine's TCP implementation has not yet provided the data it's received to the code that's reading the data (program, or library used by a program), it should do so at that point. To quote RFC 793, the official specification for TCP:
The data that flows on a connection may be thought of as a stream of octets. The sending user indicates in each SEND call whether the data in that call (and any preceeding calls) should be immediately pushed through to the receiving user by the setting of the PUSH flag.
A sending TCP is allowed to collect data from the sending user and to send that data in segments at its own convenience, until the push function is signaled, then it must send all unsent data. When a receiving TCP sees the PUSH flag, it must not wait for more data from the sending TCP before passing the data to the receiving process.
There is no necessary relationship between push functions and segment boundaries. The data in any particular segment may be the result of a single SEND call, in whole or part, or of multiple SEND calls.
The purpose of push function and the PUSH flag is to push data through from the sending user to the receiving user. It does not provide a record service.
咱們實驗中的web server端的HTTP層就至關於引文中的sending user,實驗中的web browser端的HTTP層就至關於引文中的receving process。
PSH flag的做用有2方面:
所以,web server所在機器的TCP協議在發送一個HTTP reponse時,當它意識到這是最後一個TCP segment時,就會加上PSH flag,而後全部buffer中還沒有發送的數據都會被髮送出去;而web browser所在機器的TCP協議在看到一個TCP segment帶有PSH flag時,就會意識到已經收到足夠信息了,應當當即把到目前爲止已經收到的信息交給上層應用(即HTTP協議)。
簡單的說,PSH flag有點像咱們寫文件時的flush操做。
還有幾點,稍微提一下: