欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

試解析Tomcat運行原理(一)--- socket通訊

系統(tǒng) 2263 0

  關(guān)于這篇文章也確實籌劃了很久,今天決定開篇寫第一篇,說起 tomcat 首先很容易聯(lián)想到 IIS ,因為我最開始使用的就是 .net 技術(shù),我第一次使用 asp 寫學生成績管理系統(tǒng)后,很茫然如何讓別人都能看到或者說使用這個系統(tǒng)呢?由此認識了 IIS ,它是一個 web 容器,天生的多線程,及時響應用戶提交的請求返回 html 頁面,這就是我了解的最初的 web 容器的功能,由此我們來認識 tomcat 也并不困難,可以的話,在了解完 tomcat 后我們可以繼續(xù)了解 jboss jetty 等,好我們進入主題。

  我們在平時開發(fā)的過程中是在使用 eclipse 時候才啟動 tomcat ,對于一個 web 容器而言,簡而言之,它是系統(tǒng)的一個守護進程,守護著對這臺服務器某個端口發(fā)起的請求,基于這一點,它就需要一個監(jiān)聽程序,這個監(jiān)聽程序來獲取來自這個端口的特定請求的數(shù)據(jù), ok ,直接點講,我們這里使用 Socket 來獲取某個端口,通常是 80 端口的 http 請求,通過簡單的 Java

  程序的死循環(huán)(粗糙的做法,后面逐步優(yōu)化)來實現(xiàn)不斷的獲取 80 端口 http 請求,來達到監(jiān)聽 80 端口 http 請求的目的。j ava.net包 下面的 Socket ServerSocket 兩個類就能實現(xiàn)我們對 8080 端口的監(jiān)聽,去除中間的邏輯代碼,我們只看這個兩個類的演繹的話如下:

?

      
        1
      
       ServerSocket serverSocket = 
      
        new
      
       ServerSocket(8080, 1, InetAddress.getByName("10.10.10.106"));
    

?

  對本機的 8080 端口進行監(jiān)聽

?

      
        1
      
       socket =
      
         serverSocket.accept();             


      
      
        2
      
       input =
      
         socket.getInputStream(); 


      
      
        3
      
       output = socket.getOutputStream(); 
    

?

  以上代碼就是獲取監(jiān)聽結(jié)果。

  這是最簡單和最精簡的Socket 通訊原理,基于這個核心點我們來開發(fā)一個簡易的,可以提供靜態(tài)頁面訪問的? custom?tomcat ,準備一個 index.html 文件放到 /home/webroot 目錄下,那么除去拓展上面代碼外,我們還需要一個 Response 和一個 Request

  類設(shè)計如下:

  HttpServer :?主函數(shù)所在類,負載啟動 ServerSocket 和?操作整合 Socket 監(jiān)聽到的數(shù)據(jù),以及返回結(jié)果,即操作 Response Request

  Request:? 封裝 Socket 監(jiān)聽到的用戶端請求,包括請求的 http?uri 信息。

  Response :?封裝需要推送到客戶端的結(jié)果數(shù)據(jù),即我們需要根據(jù) http?uri? 去本機尋找相應的資源,寫給客戶端。

  言簡意賅,進入代碼,首先? Request 類代碼:

?

      
         1
      
      
        public
      
      
        class
      
      
         Request 


      
      
         2
      
      
        {


      
      
         3
      
      
        private
      
      
         InputStream input;


      
      
         4
      
      
        private
      
      
         String uri;


      
      
         5
      
      
         6
      
      
        public
      
      
         Request(InputStream input) {


      
      
         7
      
      
        this
      
      .input =
      
         input;


      
      
         8
      
      
            }


      
      
         9
      
      
        10
      
      
        public
      
      
        void
      
      
         parse()


      
      
        11
      
      
            {


      
      
        12
      
               StringBuffer request = 
      
        new
      
       StringBuffer(2048
      
        );


      
      
        13
      
      
        int
      
      
         i;


      
      
        14
      
      
        byte
      
      [] buffer = 
      
        new
      
      
        byte
      
      [2048
      
        ];


      
      
        15
      
      
        try
      
      
        16
      
      
                { 


      
      
        17
      
                    i =
      
         input.read(buffer);


      
      
        18
      
      
                }


      
      
        19
      
      
        catch
      
      
        (IOException e) 


      
      
        20
      
      
                { 


      
      
        21
      
      
                     e.printStackTrace(); 


      
      
        22
      
                    i = -1
      
        ; 


      
      
        23
      
      
                }


      
      
        24
      
      
        25
      
      
        for
      
       (
      
        int
      
       j=0; j<i; j++
      
        ) 


      
      
        26
      
      
                {


      
      
        27
      
                   request.append((
      
        char
      
      
        ) buffer[j]);


      
      
        28
      
      
                } 


      
      
        29
      
      
                System.out.print(request.toString()); 


      
      
        30
      
               uri =
      
         parseUri(request.toString());


      
      
        31
      
      
            }


      
      
        32
      
      
        33
      
      
        private
      
      
         String parseUri(String requestString) 


      
      
        34
      
      
            {  


      
      
        35
      
      
        int
      
      
         index1, index2; 


      
      
        36
      
               index1 = requestString.indexOf(' '
      
        );


      
      
        37
      
      
        if
      
       (index1 != -1
      
        ) { 


      
      
        38
      
                   index2 = requestString.indexOf(' ', index1 + 1
      
        );


      
      
        39
      
      
        if
      
       (index2 >
      
         index1) 


      
      
        40
      
      
        return
      
       requestString.substring(index1 + 1
      
        , index2); 


      
      
        41
      
      
                    }  


      
      
        42
      
      
        return
      
      
        null
      
      
        ;


      
      
        43
      
      
            }


      
      
        44
      
      
        45
      
      
        public
      
      
         String getUri() 


      
      
        46
      
      
            {


      
      
        47
      
      
        return
      
      
         uri;


      
      
        48
      
      
            }


      
      
        49
      
       }
    

?

  代碼解釋:類包括一個屬性和兩個方法, input 屬性即是從 Socket 監(jiān)聽到的信息, Socket 會將監(jiān)聽到的信息放入一個 InputStream 中,我們使用 Reqeust 類的 Input 屬性來接受。接收到輸入流后,在 parse 中對這個輸入流進行解析成字符串,即對 Http 請求進行拆解,得到完整的 Http?URL ,所以這個方法是私有的,是類存在意義的核心所在,而提供的對外方法 parseUri 是負載將 parse 解析的 url 結(jié)果提供給外界,即,客戶端發(fā)來請求那個文件,具體的是最終提供給 Response 類, Response 類得到這個文件名稱后,去本地制定目錄讀取文件。 Tomcat 中通常就是 webapps 目錄啦,很熟悉了吧,哈哈。

  Response 類如何實現(xiàn)這個讀取文件的歷史使命呢,代碼如下 :

?

      
         1
      
      
        public
      
      
        class
      
      
         Response {


      
      
         2
      
      
         3
      
      
        private
      
      
        static
      
      
        final
      
      
        int
      
       BUFFER_SIZE = 1024
      
        ; 


      
      
         4
      
      
            Request request; 


      
      
         5
      
      
            OutputStream output;


      
      
         6
      
      
         7
      
      
        public
      
      
         Response(OutputStream output) 


      
      
         8
      
      
            { 


      
      
         9
      
      
        this
      
      .output =
      
         output;


      
      
        10
      
      
            }


      
      
        11
      
      
        12
      
      
        public
      
      
        void
      
      
         setRequest(Request request)


      
      
        13
      
      
            {


      
      
        14
      
      
        this
      
      .request =
      
         request;


      
      
        15
      
      
            }


      
      
        16
      
      
        17
      
      
        public
      
      
        void
      
       sendStaticResource() 
      
        throws
      
      
         IOException


      
      
        18
      
      
            {


      
      
        19
      
      
        byte
      
      [] bytes = 
      
        new
      
      
        byte
      
      
        [BUFFER_SIZE];


      
      
        20
      
               FileInputStream fis = 
      
        null
      
      
        ;


      
      
        21
      
      
        try
      
      
        22
      
      
                {


      
      
        23
      
                       File file = 
      
        new
      
      
         File(HttpServer.WEB_ROOT, request.getUri());


      
      
        24
      
      
        if
      
      
         (file.exists())


      
      
        25
      
      
                        { 


      
      
        26
      
                               fis = 
      
        new
      
      
         FileInputStream(file); 


      
      
        27
      
      
        int
      
       ch = fis.read(bytes, 0
      
        , BUFFER_SIZE); 


      
      
        28
      
      
        while
      
       (ch!=-1
      
        ) { 


      
      
        29
      
                                   output.write(bytes, 0
      
        , ch); 


      
      
        30
      
                                   ch = fis.read(bytes, 0
      
        , BUFFER_SIZE);


      
      
        31
      
      
                                }


      
      
        32
      
      
                        }


      
      
        33
      
      
        else
      
      
        34
      
      
                        {


      
      
        35
      
                           String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +


      
        36
      
                               "Content-Type: text/html\r\n" + 


      
        37
      
                               "Content-Length: 23\r\n" +


      
        38
      
                               "\r\n" +


      
        39
      
                               "<h1>File Not Found</h1>"
      
        ;


      
      
        40
      
      
                            output.write(errorMessage.getBytes());


      
      
        41
      
      
                        }


      
      
        42
      
      
                }


      
      
        43
      
      
        catch
      
      
        (Exception e) 


      
      
        44
      
      
                {


      
      
        45
      
      
                        System.out.println(e.toString());


      
      
        46
      
      
                }


      
      
        47
      
      
        finally
      
      
        {


      
      
        48
      
      
                    fis.close();


      
      
        49
      
      
                }


      
      
        50
      
      
        51
      
      
            }


      
      
        52
      
       }
    

?

  代碼解釋: Response 一共三個屬性,一個方法。三個屬性,一個是設(shè)置屬性, BUFFER_SIZE 設(shè)置讀寫字節(jié)流大小,關(guān)于讀寫文件,我個人覺得和服務器的性能和程序性能息息相關(guān),不宜設(shè)定過大或過小(此處有不同見解的同仁歡迎來噴,我對這塊理解目前限于此)。 Reqeust 屬性,對照前文呼應, Response 需要獲取 Request 類的 uri 結(jié)果信息,所以這里放了一個 Request 屬性,獲取 uri Output ,就不用說了,也是這個類存在的核心意義,依照 Request 類提供的 uri 信息,在本地讀寫文件后,形成一個輸出來,存放到 output 中,那么這項工作就由 sendStaticResource 這個共有方法完成啦。

  好,代碼到這個,可以說我們大家已經(jīng)看到一個 tomcat 模型了,有點萬事俱備,只欠東風的感覺,客戶端發(fā)起請求, Response Reqeust 有了,那么繼續(xù)往上游考慮, Reqeust 依賴于客戶端的請求,自然以來于 Socket 數(shù)據(jù)。我們在這里做得簡便一點,將 ServerSocket Socket 封裝到一個 HttpServer 類中來,代碼如下:

?

      
         1
      
      
        public
      
      
        class
      
      
         HttpServer {


      
      
         2
      
      
         3
      
      
        public
      
      
        static
      
      
        final
      
       String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot"
      
        ;


      
      
         4
      
      
        private
      
      
        static
      
      
        final
      
       String SHUTDOWN_COMMAND = "/SHUTDOWN"
      
        ;


      
      
         5
      
      
        private
      
      
        boolean
      
       shutdown = 
      
        false
      
      
        ;


      
      
         6
      
      
        public
      
      
        static
      
      
        void
      
      
         main(String[] args)


      
      
         7
      
      
            {


      
      
         8
      
               HttpServer httpServer = 
      
        new
      
      
         HttpServer();


      
      
         9
      
      
                httpServer.await();


      
      
        10
      
      
            }


      
      
        11
      
      
        12
      
      
        public
      
      
        void
      
      
         await()


      
      
        13
      
      
            {


      
      
        14
      
               ServerSocket serverSocket = 
      
        null
      
      
        ;


      
      
        15
      
               Integer port = 8080
      
        ; 


      
      
        16
      
      
        try
      
      
        17
      
      
                { 


      
      
        18
      
                   serverSocket =  
      
        new
      
       ServerSocket(port, 1, InetAddress.getByName("10.10.10.106"
      
        )); 


      
      
        19
      
      
                } 


      
      
        20
      
      
        catch
      
      
        (IOException e)     


      
      
        21
      
      
                { 


      
      
        22
      
      
                    e.printStackTrace(); 


      
      
        23
      
                   System.exit(1
      
        ); 


      
      
        24
      
      
                } 


      
      
        25
      
      
        26
      
      
        while
      
      (!
      
        shutdown)


      
      
        27
      
      
                {


      
      
        28
      
                   Socket socket = 
      
        null
      
      
        ;


      
      
        29
      
                   InputStream input = 
      
        null
      
      
        ;


      
      
        30
      
                   OutputStream output = 
      
        null
      
      
        ;


      
      
        31
      
      
        try
      
      
        32
      
      
                    { 


      
      
        33
      
                       socket =
      
         serverSocket.accept();


      
      
        34
      
      
        35
      
                       input =
      
         socket.getInputStream(); 


      
      
        36
      
                       output =
      
         socket.getOutputStream(); 


      
      
        37
      
                       Request request = 
      
        new
      
      
         Request(input); 


      
      
        38
      
      
                        request.parse(); 


      
      
        39
      
                       Response response = 
      
        new
      
      
         Response(output);


      
      
        40
      
      
                        response.setRequest(request); response.sendStaticResource();  socket.close(); 


      
      
        41
      
                       shutdown =
      
         request.getUri().equals(SHUTDOWN_COMMAND);


      
      
        42
      
      
                    }


      
      
        43
      
      
        catch
      
      
        (Exception e) 


      
      
        44
      
      
                    {


      
      
        45
      
                       e.printStackTrace();
      
        continue
      
      
        ;


      
      
        46
      
      
                    }


      
      
        47
      
      
                }


      
      
        48
      
      
            }


      
      
        49
      
       }
    

?

  代碼解釋:我們知道啟動 tomcat 之后,只要服務正常,客戶端任意時候發(fā)起一個 http 請求, tomcat 就會響應,那么這里我們肯定需要一個 while 循環(huán)來模擬不間斷的監(jiān)聽,類 await 方法就是負責不斷的獲取 socket 監(jiān)聽到的結(jié)果,有立刻調(diào)動 Reqeust Response 進行響應,加入主函數(shù),為的是我們這個是模擬的控制臺程序,需要一個程序入口, main 函數(shù)就是程序入口。此外, HttpServer 類包括一個靜態(tài)屬性 SHUTDOWN_COMMAND ,輸入為 true 則停止這個 main 函數(shù),變量初始值為 false ,當客戶端也就是 Request 響應得到客戶端輸入? http://10.10.10.108:8080/SHUTDOWN 時候,則變量在 while 中會置成 true ,緊接著停止 main ,結(jié)束應用程序進程。

  在 eclipse 中或者在命令行中啟動這個 main 函數(shù),命令行則是輸入? java?HttpServer.java eclipse 則是在 main 函數(shù)中右鍵? run?as?application 啟動。 我們打開瀏覽器,輸入? http://10.10.10.108:8080/index.html, 回車結(jié)果如下:

試解析Tomcat運行原理(一)--- socket通訊

  本地文件:

  好了,夜深啦,就此擱筆了,拋磚引玉,歡迎提議和討論,這個系列會繼續(xù)下去,直到一個完整的可以響應一個java action請求的custom tomcat產(chǎn)品出來。

  最后附上我的源代碼:http://files.cnblogs.com/aspnetdream/Project.zip

  參考:《How tomcat works》?作者:Budi Kurniawan & Paul Deck

?

試解析Tomcat運行原理(一)--- socket通訊


更多文章、技術(shù)交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲看| 天天色亚洲 | 成人一区二区三区四区 | 人人爱人人做 | 亚洲欧美一级久久精品 | 一级做一级爱a做片性视频视频 | 成人免费在线 | 国产成人91高清精品免费 | 正规成人啪啪 | 一区二区三区四区视频 | 国产美女主播在线观看 | 久久久久久免费一区二区三区 | 天堂资源av | 午夜精品一区二区三区在线观看 | 午夜精品在线观看 | 大学生一级毛片全黄毛片黄 | 日韩精品亚洲人成在线播放 | 欧美经典剧情系列h版在线观看 | 午夜精品视频在线观看 | 一区二区三区在线 | 网站 | 日韩视频免费 | 一级片 | 青青草国产精品欧美成人 | 精品一区二区在线观看视频 | 欧美日韩精品一区二区在线播放 | 岛国色情A片无码视频免费看 | 国产精品视频久久久 | 日韩在线免费视频观看 | 极品久久 | 日日碰狠狠添天天爽五月婷 | 欧美的| 超级在线牛碰碰视频 | 91手机在线观看 | 夜夜爽夜夜叫夜夜高潮漏水 | 国产日韩在线观看一区 | 欧美淫片 | 人人爽人人看 | 欧美专区在线 | 亚洲一区二区三区免费视频 | 九热视频在线观看 | av在线播放免费 |