利用java構(gòu)建http服務(wù)器

          Posted on 2009-12-17 17:26 terryxue 閱讀(2054) 評論(3)  編輯  收藏 所屬分類: java

          web服務(wù)器大家都會(huì)用,可是它的實(shí)現(xiàn)原理是到底如何呢,其實(shí)只要讀一下http協(xié)議,大家基本也能開發(fā)出一個(gè)簡單的web服務(wù)器出來了。

          web請求分為如下幾步

          1. 瀏覽器向服務(wù)建立TCP/IP連接,Java中通過java.net.Socket實(shí)現(xiàn)

          2. Web瀏覽器向Web服務(wù)器發(fā)送請求命令。通過Socket的輸出流向服務(wù)器寫如下信息:

            GET /uri HTTP/1.1,很顯示第一部分為請求的方法,第二部分為請求的URI,第三部分為請求的協(xié)議

          3. Web瀏覽器發(fā)送請求頭信息。這部分包括瀏覽器的版本信息,接受的格式、編碼等,還有非常有用的一個(gè)數(shù)據(jù)Cookie也是在這里發(fā)送的。

          4. 頭信息發(fā)送完后,發(fā)送一個(gè)空格表示結(jié)束,如果是post請求,則繼續(xù)發(fā)送Post正文。

          5. Web服務(wù)器做出應(yīng)答,如返回"HTTP/1.1 200  OK",表示請求成功,或者返回404,500等狀態(tài)信息表示找不到頁面或服務(wù)器錯(cuò)誤。

          6. Web服務(wù)器發(fā)送應(yīng)答頭信息,這部分表示了返回的內(nèi)容類型(如是gif還是exe還是html等),返回的數(shù)據(jù)的編碼,長度,當(dāng)然還有Cookie(通過set-Cookie來發(fā)送)

          7. 在發(fā)送完應(yīng)答頭后,則發(fā)送一個(gè)空行。如果有響應(yīng)正文,則在后面繼續(xù)發(fā)送響應(yīng)內(nèi)容。

          8. 關(guān)閉TCP/IP連接

          以下代碼簡單的模擬了這一過程。

          客戶端代碼:

          //1. 建立到服務(wù)器的連接
          private void connect() throws Exception{
            socket 
          = new Socket("serverName"80);        
          }

          //2. 發(fā)送請求命令
          private void sendRequestCommand() throws Exception{
            OutputStream os 
          = socket.getOutputStream();
            os.write(
          "GET /index.html HTTP/1.1\n".getBytes());
          }

          //3. 發(fā)送請求頭信息
          private void sendHeader() throws Exception{
            OutputStream os 
          = socket.getOutputStream();
            os.write((
          "Accept: */*\n" +
              
          "Accept-Language: zh-cn;q=0.5\n" +
              
          "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; CIBA; .NET CLR 2.0.50727)\n" +
              
          "Host: 192.168.1.110\n" +
              
          "Connection: Keep-Alive\n" +
              
          "\n").getBytes());
            os.flush();
          }

          //4. 檢測服務(wù)器發(fā)送回來的響應(yīng)
          private void getResponse() throws Exception{
            InputStream is 
          = socket.getInputStream();
            
          while(is.available() == 0){
              Thread.sleep(
          10);
            }

            BufferedReader br 
          = new BufferedReader(new 
              InputStreamReader(is, 
          "utf-8"));
            String line 
          = null;
            
          while((line = br.readLine()) != null{
              System.out.println(line);
            }

          }

          服務(wù)器代碼如下:
          private ServerSocket server;    
              
          public void start() throws Exception{
                  server 
          = new ServerSocket(80);//監(jiān)聽80端口        
                  accept();
              }

              
              
          private void accept(){
                  
          new Thread(){
                      
          public void run(){
                          
          while(true){
                              
          try {
                                  System.out.println(
          "accept");
                                  Socket socket 
          = server.accept();
                                  System.out.println(
          "new client.");
                                  processRequest(socket);
                              }
           catch (IOException e) {
                                  e.printStackTrace();
                              }

                          }

                      }

                  }
          .start();
              }

              
              
          private void processRequest(Socket socket){
                  
          new RequestProcessor(socket).start();
              }

              
          //將每個(gè)請求用一個(gè)單獨(dú)的線程來進(jìn)行處理,這樣可以實(shí)現(xiàn)多個(gè)請求的并發(fā)處理功能
              private class RequestProcessor extends Thread{
                  Socket socket;
                  RequestProcessor(Socket socket)
          {
                      
          this.socket = socket;
                  }

                  
          public void run(){
                      
          try {
                          InputStream is 
          = socket.getInputStream();
                          
          while(is.available() == 0){
                              Thread.sleep(
          10); //檢測客戶端是否發(fā)送過來了請求數(shù)據(jù)
                          }

                          
                          
          while(is.available() > 0){
                              System.out.print((
          char)is.read());//打印發(fā)送過來的所有數(shù)據(jù),可以保存起來以做進(jìn)一步的處理
                          }

                          
                          
                          String info 
          = "HTTP/1.1 200 OK\n" +
                                  
          "Server: Apache-Coyote/1.1\n" +
                                  
          "Content-Type: text/html;charset=utf-8\n" +
                                  
          "Content-Length: 1021\n" +
                                  
          "Date: Wed, 09 Dec 2009 05:00:27 GMT\n" +
                                  
          "\n";                
                          OutputStream os 
          = socket.getOutputStream();
                          os.write(info.getBytes(
          "utf-8"));
                          os.flush();
                          
                          FileInputStream fis 
          = new FileInputStream("webRoot/index.html");//假設(shè)用戶請求的是index.html,讀取該文件做為響應(yīng)
                          byte data[] = new byte[1024*10];
                          
          int length = 0;
                          
          while((length = fis.read(data)) > 0){
                              os.write(data, 
          0, length);
                          }
                          
                          os.flush();
                          os.close();
                      }
           catch (Exception e) {
                          
          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }

                      
                  }

              }

          Feedback

          # re: 利用java構(gòu)建http服務(wù)器  回復(fù)  更多評論   

          2009-12-17 18:13 by simaliu
          呵呵
          我也做過這方面的工作
          有興趣可以交流一下

          # re: 利用java構(gòu)建http服務(wù)器  回復(fù)  更多評論   

          2009-12-18 08:35 by mathfox
          這也能上主頁?

          # re: 利用java構(gòu)建http服務(wù)器  回復(fù)  更多評論   

          2009-12-18 08:36 by mathfox
          如果你想做web 服務(wù)器,

          請搜索how tomcat works,雖然講的是比較老的tomcat,不過還是很有參考價(jià)值的。

          我以后我仔細(xì)看看

          posts - 9, comments - 24, trackbacks - 0, articles - 0

          Copyright © terryxue

          主站蜘蛛池模板: 江阴市| 福清市| 兴宁市| 锡林郭勒盟| 万载县| 邯郸市| 织金县| 泊头市| 句容市| 旌德县| 读书| 增城市| 盖州市| 台前县| 洛扎县| 南投县| 湾仔区| 临漳县| 于田县| 张家界市| 淮阳县| 托克逊县| 屏东县| 孟州市| 鲜城| 菏泽市| 图们市| 正定县| 蒙自县| 龙江县| 丹巴县| 扬州市| 万州区| 保定市| 浠水县| 阳西县| 达孜县| 金华市| 鹿邑县| 广丰县| 镇平县|