從java 理解http互動過程,三次握手四次揮手
ip |
網絡卡地址 |
|
本機 |
192.168.8.50 |
C8-5B-76-03-AC-5B |
伺服器 |
192.168.8.240:81 |
00 0c 29 69 5f 13 |
工具:wireshark(用於監控本地網路請求)
原始碼:由於JDK提供的原始碼,只有部分的SUN原始碼,更深的原始碼沒有提供,需要跟蹤程式碼的需要自行下載jdk對應的原始碼
傳送HTTP請求的程式碼:
跟蹤程式碼也發現,前面兩步都沒有進行HTTP連線,到第三步 conn.getInputStream();才進行連線
(只要執行這部分程式碼才發現wireshark有資料),進行程式碼跟著也發現到第三步開始使用SocketPermission,
也就是socket進行連線(其實除了使用socket也沒有什麼可以使用了)。(TIP:關於socket自行百度,很多介紹文章)
下圖是監控到的請求:
本機 |
伺服器 |
|
1 |
傳送空資料 |
|
2 |
伺服器回覆空內容 |
|
3 |
傳送空資料 |
|
4 |
傳送資料 | |
5 |
伺服器響應對應的資料 ,由於資料量大需要分兩個包傳送 |
|
6 |
伺服器響應對應的資料 |
|
7 |
傳送空資料 |
|
8 |
傳送空資料 |
根據監控的到時3次握手,2次揮手也僅僅是本機揮手。沒有伺服器響應。猜想是沒有我們沒有關閉連線導致。
於是修改程式碼(找了半天沒找到關閉連線的方法,要用HttpURLConnection才有關閉的方法
public static void main(String[] args) throws IOException { /*上面構造http,Handler,對url的解析*/ URL u = new URL("http://192.168.8.240:81/intfweb/index.html"); /*初始化連線的資料*/ HttpURLConnection conn = (HttpURLConnection) u.openConnection(); //這一步開始連線 InputStream in = conn.getInputStream(); conn.disconnect(); StringBuffer buf = new StringBuffer(); int t =0; while((t = in.read())!=-1) { buf.append((char)t); } System.out.println(buf.toString()); }
根據修改的程式碼進行測試:
上圖看出,沒有進行關閉的時候連線跟之前是一樣的
執行關閉程式碼,如下:(多出4次請求)
總結:
名詞解釋:
SYN表示建立連線, FIN表示關閉連線, ACK表示響應, PSH表示有 DATA資料傳輸, RST表示連線重置。
本機 |
伺服器 |
|
1 |
傳送空資料[SYN] 主機A傳送位碼為syn=1,隨機產生seq number=0的資料包到伺服器,主機B由SYN=1知道,A要求建立聯機 Seq=0 Win=64240 Len=0 MSS=1460 WS=8 SACK_PERM=1 TSV=542732994 TSER=0 |
|
2 |
伺服器回覆空內容[SYN,ACK] 主機B收到請求後要確認聯機資訊,向A傳送ack number=(主機A的seq+1),syn=1,ack=1,隨機產生seq=0的包; [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 WS=8 SACK_PERM=1 TSV=67540739 TSER=542732994 |
|
3 |
傳送空資料[ACK] 主機A收到後檢查ack number是否正確,即第一次傳送的seq number+1,以及位碼ack是否為1,若正確,主機A會再發送ack number=(主機B的seq+1),ack=1,主機B收到後確認seq值與ack=1則連線建立成功。 [ACK] Seq=1 Ack=1 Win=66560 Len=0 TSV=542732995 TSER=67540739 |
|
4 |
傳送資料[PSH,ACK] |
|
5 |
伺服器響應對應的資料 ,由於資料量大需要分兩個包傳送[ACK] |
|
6 |
伺服器響應對應的資料[PSH,ACK] |
|
7 |
傳送空資料[ACK] |
|
8 |
傳送空資料[FIN] |
|
9 |
伺服器回覆空內容[ACK] |
|
10 |
伺服器回覆空內容[FIN] |
|
11 |
傳送空資料[ACK] |
從上看出:
根據結果完全附件符合HTTP的3次握手4次揮手.在接受資料完成的時候發生一個ack,告訴服務接收完成
同時也知道使用java URL傳送請求的要記得關閉連線誒才算是完整。(其實不關閉應該也沒啥)
SYN:同步序列編號(Synchronize Sequence Numbers)。是TCP/IP建立連線時使用的握手訊號。在客戶機和伺服器之間建立正常的TCP網路連線時,客戶機首先發出一個SYN訊息,伺服器使用SYN+ACK應答表示接收到了這個訊息,最後客戶機再以ACK訊息響應。這樣在客戶機和伺服器之間才能建立起可靠的TCP連線,資料才可以在客戶機和伺服器之間傳遞。
在TCP/IP協議中,如果接收方成功的接收到資料,那麼會回覆一個ACK資料。通常ACK訊號有自己固定的格式,長度大小,由接收方回覆給傳送方。
PSH是TCP報頭中的一個標誌位,傳送方在傳送資料的時候可以設定這個標誌位.當兩個應用程式進行互動式的通訊時,有時在一端的應用程序希望在鍵入一個命令後立即就能夠收到對方的響應.在這種情況下,TCP可以使用推送(push)操作.這時,傳送端TCP將推送位元PSH置為1,並立即建立一個報文段傳送出去.接收TCP收到推送位元置1的報文段,就儘快地(即"推送向前")交付給接收應用程序,而不再等到整個緩衝都填滿了再向上互動.PSH位元也叫急迫位元.
第一次握手傳送的資料,從內容看是使用MAC地址,猜想這裡攔截到的資料是資料的報文吧,報頭這些東西沒有顯示出來。沒有在深入研究了。