先來一個講TCP、UDP和HTTP html
一、TCP/IP是個協議組,可分爲三個層次:網絡層、傳輸層和應用層。
在網絡層有IP協議、ICMP協議、ARP協議、RARP協議和BOOTP協議。
在傳輸層中有TCP協議與UDP協議。
在應用層有FTP、HTTP、TELNET、SMTP、DNS等協議。
所以,HTTP自己就是一個協議,是從Web服務器傳輸超文本到本地瀏覽器的傳送協議。
二、HTTP協議是創建在請求/響應模型上的。首先由客戶創建一條與服務器的TCP連接,併發送一個請求到服務器,請求中包含請求方法、URI、協議版本以及相關的MIME樣式的消息。服務器響應一個狀態行,包含消息的協議版本、一個成功和失敗碼以及相關的MIME式樣的消息。
HTTP/1.0爲每一次HTTP的請求/響應創建一條新的TCP連接,所以一個包含HTML內容和圖片的頁面將須要創建屢次的短時間的TCP連接。一次TCP連接的創建將須要3次握手。
另外,爲了得到適當的傳輸速度,則須要TCP花費額外的迴路連接時間(RTT)。每一次連接的創建須要這種常常性的開銷,而其並不帶有實際有用的數據,只是保證連接的可靠性,所以HTTP/1.1提出了可持續連接的實現方法。HTTP/1.1將只創建一次TCP的連接而重複地使用它傳輸一系列的請求/響應消息,所以減小了連接創建的次數和常常性的連接開銷。
web
三、結論:雖然HTTP自己是一個協議,但其最終仍是基於TCP的。不過,目前,有人正在研究基於TCP+UDP混合的HTTP協議。設計模式
Socket是什麼呢?
Socket是應用層與TCP/IP協議族通訊的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來講,一組簡單的接口就是所有,讓Socket去組織數據,以符合指定的協議。瀏覽器
這是從大的概況上描述了一下相互關係,還有一些重要的細節須要進一步瞭解,不少時候,這些細節才更重要。安全
咱們將按這樣的順序討論:服務器
至於什麼是三次握手,則能夠參考各類文檔,三次握手。能夠用一張圖來看一下:網絡
通訊最主要的是信道的安全,那就是c和s通訊,c要確保s的真實存在; s也要包裝c的真實存在。併發
那就行了: c如何保證s真實存在? 發j,必須返回k,和j+1; 這樣就驗證了;less
那麼s也須要包裝s的真實存在,一樣原理:過去的k,必須應答k+1,不然沒法正常創建。固然,加密通訊時,進一步提升安全性。這只是最小代價的驗證方式,但並非絕對安全。socket
更爲合理的解釋:
這個問題的本質是, 信道不可靠, 可是通訊雙發須要就某個問題達成一致. 而要解決這個問題, 不管你在消息中包含什麼信息, 三次通訊是理論上的最小值. 因此三次握手不是TCP自己的要求, 而是爲了知足"在不可靠信道上可靠地傳輸信息"這一需求所致使的. 請注意這裏的本質需求,信道不可靠, 數據傳輸要可靠. 三次達到了, 那後面你想接着握手也好, 發數據也好, 跟進行可靠信息傳輸的需求就不要緊了.由於驗證信道安全的事情已經結束,但理論上是沒法絕對安全的,由於驗證的老是當前的狀態,下一刻也許被攻擊或者失去聯繫(好比服務器掉電,戰爭中的電報機忽然被炸燬)。
所以,若是信道是可靠的, 即不管何時發出消息, 對方必定能收到, 或者你不關心是否要保證對方收到你的消息, 那就能像UDP那樣直接發送消息就能夠了.」。這可視爲對「三次握手」目的的另外一種解答思路。
C發送請求,S應答並分配資源 ;
一旦S的應答沒有到達C端,C認爲鏈接未創建,而S認爲創建了
S會在一段時間內保留分配的資源
若是大量C這樣請求,S會崩潰。
若是是四次握手呢?
其實之後能夠無限次的握手,是更加安全的驗證通道,最終仍是爲了傳輸」數據「,這是一種」安全性「和」代價「的平衡策略。爲了安全,你能夠驗證四次,甚至五次,只是這增長了成本,相對提升了一些信道安全的驗證。
注:那張圖我寫成了」四次握手「,實際上是錯的,應該是四次揮手。
1 String currentUrl=「http://www.cnblogs.com/notech」; //URL ?後面的內容爲HTTP請求的正文URL url = new URL(currentUrl);
2
3 HttpURLConnection httpurlconnection = url.openConnection();//下面的設置對應HTTP請求中的消息報頭
4 httpurlconnection.setRequestProperty("User-Agent",CommonValues.User_Agent); 5 httpurlconnection.setRequestProperty("Accept",CommonValues.Accept); 6 httpurlconnection.setRequestProperty("Accept-Charset",CommonValues.Accept_Charset); 7 httpurlconnection.setRequestProperty("Accept-Language",CommonValues.Accept_Language); 8 httpurlconnection.setRequestProperty("Connection",CommonValues.Connection); 9 httpurlconnection.setRequestProperty("Keep-Alive",CommonValues.Keep_Alive); 10 httpurlconnection.setConnectTimeout(CommonValues.ConnectionTimeOut); 11 httpurlconnection.setReadTimeout(CommonValues.ReadTimeOut); 12
13 httpurlconnection.connect(); 14
15 int responsecode = httpurlconnection.getResponseCode(); 16
17 if(responsecode == HttpURLConnection.HTTP_OK) //對應HTTP響應中狀態行的響應碼{ 18 //操做請求流,這裏對應HTTP響應中的響應正文
19 } 20
21 if (httpurlconnection != null) 22 { 23 httpurlconnection.disconnect(); 24 }
更多的參數能夠參考官方文檔:也就是http協議的官方文檔。
http://www.w3.org/Protocols/rfc2616/rfc2616.html
剛纔提到了,一個重要的則是長鏈接的創建,提升網絡使用率。固然更爲全面的區別,能夠參考一篇論文。更加全面。
Key Differences between HTTP/1.0 and HTTP/1.1
若是由於國內限制訪問不少國外ip,我拷貝一段重要的:
We structure our discussion by (somewhat arbitrarily) dividing the protocol changes into nine major areas:
1.
Extensibility
2.
Caching
3.
Bandwidth optimization
4.
Network connection management
5.
Message transmission
6.
Internet address conservation
7.
Error notification
8.
Security, integrity, and authentication
9.
Content negotiation
通訊雙方創建TCP鏈接後,主動關閉鏈接的一方就會進入TIME_WAIT狀態。
客戶端主動關閉鏈接時,會發送最後一個ack後,而後會進入TIME_WAIT狀態,再停留2個MSL時間(後有MSL的解釋),進入CLOSED狀態。
使用netstat –an命令會看到不少TIME_WAIT的TCP連接。
更多:
LISTEN:(Listening for a connection.) |
偵聽來自遠方的TCP端口的鏈接請求 |
SYN-SENT:(Active; sent SYN. Waiting for a matching connection request after having sent a connection request. |
再發送鏈接請求後等待匹配的鏈接請求 |
SYN-RECEIVED:(Sent and received SYN. Waiting for a confirming connection request acknowledgment after having both received and sent connection requests.) |
再收到和發送一個鏈接請求後等待對方對鏈接請求的確認 |
ESTABLISHED:(Connection established.) |
表明一個打開的鏈接 |
FIN-WAIT-1:(Closed; sent FIN.) |
等待遠程TCP鏈接中斷請求,或先前的鏈接中斷請求的確認 |
FIN-WAIT-2:(Closed; FIN is acknowledged; awaiting FIN.) |
從遠程TCP等待鏈接中斷請求 |
CLOSE-WAIT:(Received FIN; waiting to receive CLOSE.) |
等待從本地用戶發來的鏈接中斷請求 |
CLOSING:(Closed; exchanged FIN; waiting for FIN.) |
等待遠程TCP對鏈接中斷的確認 |
LAST-ACK:(Received FIN and CLOSE; waiting for FIN ACK.) |
等待原來的發向遠程TCP的鏈接中斷請求的確認 |
TIME-WAIT:(In 2 MSL (twice the maximum segment length) quiet wait after close. ) |
等待足夠的時間以確保遠程TCP接收到鏈接中斷請求的確認 |
CLOSED:(Connection is closed.) |
沒有任何鏈接狀態 |
咱們知道HTTP協議採用「請求-應答」模式,當使用普通模式,即非KeepAlive模式時,每一個請求/應答客戶和服務器都要新建一個鏈接,完成 以後當即斷開鏈接(HTTP協議爲無鏈接的協議);當使用Keep-Alive模式(又稱持久鏈接、鏈接重用)時,Keep-Alive功能使客戶端到服 務器端的鏈接持續有效,當出現對服務器的後繼請求時,Keep-Alive功能避免了創建或者從新創建鏈接。
http 1.0中默認是關閉的,須要在http頭加入"Connection: Keep-Alive",才能啓用Keep-Alive;http 1.1中默認啓用Keep-Alive,若是加入"Connection: close ",才關閉。目前大部分瀏覽器都是用http1.1協議,也就是說默認都會發起Keep-Alive的鏈接請求了,因此是否能完成一個完整的Keep- Alive鏈接就看服務器設置狀況。
有人會問,time通常多少時間?
Keepalive messages were not officially supported in HTTP 1.0. In HTTP 1.1 all connections are considered persistent, unless declared otherwise[1]. However, the default keepalive timeout of Apache 2.0 httpd is as little as 15 seconds] and for Apache 2.2 only 5 seconds. The advantage of a short timeout is the ability to deliver multiple components of a web page quickly while not tying up multiple server processes or threads for too long.
固然tcp也有keepalive,不過只是驗證tcp是否存活,和http的keepalive不是一回事,詳細的能夠參考下面的文檔:
零零碎碎整理了一些,有些細節還需繼續深刻,並把理論和實踐(代碼)相結合,最好結合官方文檔。防止誤解和遺漏。
一些參考文章: