qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          淺析Java web程序之客戶端和服務器端交互原理

          1、協議

            a. TCP/IP整體構架概述

            TCP/IP協議并不完全符合 OSI的七層參考模型。傳統的開放式系統互連參考模型,是一種通信協議的7層抽象的參考模型,其中每一層執行某一特定任務。該模型的目的是使各種硬件在相 同的層次上相互通信。這7層是:物理層、數據鏈路層、網路層、傳輸層、話路層、表示層和應用層。而TCP/IP通訊協議采用了4層的層級結構,每一層都呼 叫它的下一層所提供的網絡來完成自己的需求。這4層分別為:

            i. 應用層:應用程序間溝通的層,如超文本傳送協議(HTTP)、簡單電子郵件傳輸(SMTP)、文件傳輸協議(FTP)、網絡遠程訪問協議(Telnet)等。

            ii. 傳輸層:在此層中,它提供了節點間的數據傳送服務,如傳輸控制協議(TCP)、用戶數據報協議(UDP)等,TCP和UDP給數據包加入傳輸數據并把它傳輸到下一層中,這一層負責傳送數據,并且確定數據已被送達并接收。

            iii. 互連網絡層:負責提供基本的數據封包傳送功能,讓每一塊數據包都能夠到達目的主機(但不檢查是否被正確接收),如網際協議(IP)。

            iv. 網絡接口層:對實際的網絡媒體的管理,定義如何使用實際網絡(如Ethernet、Serial Line等)來傳送數據。

            b. HTTP協議介紹:

            i. HTTP是一種超文本傳送協議(HyperText Transfer Protocol),是一套計算機在網絡中通信的一種規則。在TCP/IP體系結構中,HTTP屬于應用層協議,位于TCP/IP協議的頂層

            ii. HTTP是一種無狀態的的協議,意思是指 在Web 瀏覽器(客戶端)和 Web 服務器之間不需要建立持久的連接。整個過程就是當一個客戶端向服務器端發送一個請求(request),然后Web服務器返回一個響應 (response),之后連接就關閉了,在服務端此時是沒有保留連接的信息。

            iii. HTTP 遵循 請求/響應(request/response) 模型的,所有的通信交互都被構造在一套請求和響應模型中。

            iv. 瀏覽WEB時,瀏覽器通過HTTP協議與WEB服務器交換信息,Web服務器向Web瀏覽器返回的文件都有與之相關的類型,這些信息類型的格式由MIME定義。

            c. 協議的java實現方式

            不論是TCP/IP協議也好,還是HTTP協議也好,java都是通過套接字(java.net.Socket)來實現的,可以參考我的另一篇技術博客:一個項目看java TCP/IP Socket編程(1.3版)

            2、HTTP報文接口及客戶端和服務器端交互原理

            a. HTTP定義的事務處理由以下四步組成:

            i. 建立連接:

             例如我在瀏覽器里輸入 http://cuishen.iteye.com,客戶端請求這個地址時即打開了web服務器HTTP端口的一個套接字。因為在網絡中間作為傳遞數據的 實體介質就是網線,數據實質上是通過IO流進行輸出和輸入,這就不難理解我們為什么在寫一個Servlet的時候要引用 import java.io.*; 的原因 ,包括我們在向客戶端回發結果的時候要用到PrintWriter對象的println()方法。其實請求的這個地址還要加上端口號80,80可以不寫, 是因為瀏覽器默認的端口號是80。

            在Java底層代碼中是這樣實現的,只不過它們已經幫我們做了。

          1. Socket socket = new Socket("cuishen.iteye.com",80);    
          2. InputStream in = socket.getInputStream();    
          3. OutputStream out = socket.getOutputStream();

            ii. 客戶端發送HTTP請求報文(request)

            一旦建立了TCP連接,Web瀏覽器就會向Web服務器發送請求命令,是一個ASCII文本請求行,后跟0個或多個HTTP頭標,一個空行和實現請求的任意數據。

          即報文分四個部分:請求行,請求頭標,空行和請求數據

            1)請求行

            請求行由三個標記組成:請求方法、請求URL和HTTP版本,中間用空格分開

            例如: GET cuishen.iteye.com/blog/242842 HTTP/1.1

            HTTP規范定義了8種可能的請求方法:(最常見的就是 GET 和 POST 兩種方法)

            ● GET -- 檢索URI中標識資源的一個簡單請求
            ● HEAD -- 與GET方法相同,服務器只返回狀態行和頭標,并不返回請求文檔
            ● POST -- 服務器接受被寫入客戶端輸出流中的數據的請求
            ● PUT -- 服務器保存請求數據作為指定URI新內容的請求
            ● DELETE -- 服務器刪除URI中命名的資源的請求
            ● OPTIONS -- 關于服務器支持的請求方法信息的請求
            ● TRACE -- Web服務器反饋Http請求和其頭標的請求
            ● CONNECT -- 已文檔化但當前未實現的一個方法,預留做隧道處理

            2)請求頭標

            請求頭標:由key :value 健值組成,每行一對。請求頭標用來通知服務器有關客戶端的功能和標識。

            HOST -- 請求的哪一個服務器端地址,主地址,比如:我的技術blog:cuishen.iteye.com

            User-Agent -- 用戶即客戶端可以使用的瀏覽器 ,如: Mozilla/4.0

            Accept -- 即客戶端可以接受的MIME 類型列表,如image/gif、text/html、application/msword

            Content-Length -- 只適用于POST請求,以字節給出POST數據的尺寸

            3)空行

            發送回車符和退行,通知服務器以下不再有頭標。

            4)請求數據

            使用POST傳送數據,最常使用的是Content-Type和Content-Length頭標。

            請求報文總結:

            我們可以這樣寫出一個標準的 HTTP請求:

          POST /blog/242842 HTTP1.1
          HOST: cuishen.iteye.com/
          User-Agent: Mozilla/4.0
          Accpt: image/gif,text/html,application/pdf,image/png...
          key=value&key=value&key=value...... (POST()請求的數據)

            這上面的一個例子意思是:

          我要去訪問的服務器端的地址是cuishen.iteye.com/ 它下面的資源 /blog/242842
          連起來就是: cuishen.iteye.com/blog/242842
          這個頁面用的是 HTTP1.1 規范,我的瀏覽器版本是Mozilla/4.0
          可以支持的MIME格式為 image/gif,text/html,application/pdf,image/png...等等

          這個MIME格式我們在servlet中寫法是:response.setContentType("text/html;charset=gb2312");
          或者在jsp中寫法是:<%@ page contentType="text/html;charset=gb2312"%>
          或者在html中寫法是:<meta http-equiv="content-Type" content="text/html; charset=gb2312">

            (c).空行:最后一個響應頭標之后是一個空行,發送回車符和退行,表明服務器以下不再有頭標。

            (d).響應數據:HTML文檔和圖像等,也就是HTML本身。out.println("<html>......");寫到客戶端。

          1. <html>    
          2. <head>    
          3. <title>Welcome to cuishen's IT blog</title>    
          4. </head>    
          5. <body>    
          6. <!-- 這里是具體的內容,看到了這里    
          7. 相信大家對 HTTP 工作原理及客戶端與服務器交互過程已經很清楚了吧    
          8. -->     
          9. </body>    
          10. </html>

            iv. 服務器端關閉連接,客戶端解析回發響應報文,恢復頁面

            1)瀏覽器先解析狀態行,查看請求是否成功的狀態代碼--HTTP響應碼:404 400 200 ....

            2)解析每一個響應頭標,如:

          ContentType: text/html;charset=gb2312
          Content-Length: 122 --- 響應中的字節數,只在瀏覽器使用永久(Keep-alive)HTTP連接時需要。

            3)讀取響應數據HTML,根據標簽<html></html>中的內容恢復標準的HTML格式頁面或者其它。

            4)一個HTML 文檔可能包含其它的需要被載入的資源,瀏覽器會識別,并對這些資源再進行額外的請求,這個過程可以是循環的方式一直到所有的數據都按照響應頭標中規定的格式恢復到頁面中。

            5)數據傳送完畢,服務器端關閉連接,即無狀態協議。

            3、總結

            不要被高深的名詞和理論嚇到,其實HTTP客戶端和服務器端的交互原理很簡單:即先是瀏覽器和服務器端建立Socket無狀態連接,也就是短連 接,然后通過IO流進行報文信息(這個報文是嚴格遵循HTTP報文接口的)的交互,最后會話結束后就關閉連接。對于這些底層的協議和報文的打包解包交互的 實現,其實java和瀏覽器早都已經封裝好了,程序員只要專注于業務邏輯的實現就行啦,這些都不必關心!!


          posted on 2012-05-11 09:48 順其自然EVO 閱讀(431) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2012年5月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 宜川县| 长海县| 六枝特区| 垦利县| 芜湖市| 泽普县| 鹤庆县| 革吉县| 苏尼特右旗| 阳春市| 林周县| 朝阳区| 太保市| 靖宇县| 同江市| 突泉县| 庆安县| 深泽县| 塘沽区| 福贡县| 建宁县| 滁州市| 桦甸市| 伊川县| 定州市| 钟山县| 建平县| 泽库县| 宜丰县| 镇安县| 姜堰市| 保山市| 灌云县| 永川市| 固原市| 洛宁县| 章丘市| 无棣县| 江津市| 平乐县| 阆中市|