<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • x
    x

    Java網絡編程:實現HTTP模擬器

    發布時間:2011-4-4 18:13    發布者:1640190015
    關鍵詞: HTTP , java , 模擬器 , 網絡編程
    在討論HTTP協議的具體請求和響應頭字段之前,讓我們先來利用以前所學的知識來實現一個HTTP模擬器。所謂HTTP模擬器就是可以在用戶輸入HTTP的請求消息后,由這個模擬器將HTTP請求發送給相應的服務器,再接收服務器的響應消息。這個HTTP模擬器有幾下特點:
        1.  可以手工輸入HTTP請求,并向服務器發送。
        2.  接收服務器的響應消息。
        3.  消息頭和實體內容分段顯示,也就是說,并不是象Telnet等客戶端一樣將HTTP響
        應消息全部顯示,而是先顯示消息頭,然后由用戶決定是否顯示實體內容。
        4.  集中發送請求。這個HTTP模擬器和Telnet不同的是,并不是一開始就連接服務器,
        而是將域名、端口以及HTTP請求消息都輸完后,才連接服務器,并將這些請求發送給服務器。這樣做的可以預防服務器提前關閉網絡連接的現象。
        5. 可以循環做上述的操作。
        從以上的描述看,要實現這個HTTP模擬器需要以下五步:
        1.  建立一個大循環,在循環內部是一個請求/響應對。這樣就可以向服務器發送多次請求/響應以了。下面的四步都是被包括在循環內部的。
        2.  從控制臺讀取域名和端口,這個功能可以由readHostAndPort(……)來完成。
        3.  從控制臺讀取HTTP請求消息,這個功能由readHttpRequest(……)來完成。
        4.  向服務器發送HTTP請求消息,這個功能由sendHttpRequest()來完成。
        5.  讀取服務器回送的HTTP響應消息,這個功能由readHttpResponse(……)來完成。
        下面我們就來逐步實現這五步:
        一、建立一個大循環
        在建立這個循環之前,先建立一個中叫HttpSimulator的類,并在這個類中定義一個run方法用來運行這個程序。實現代碼如下:
        001  package http;
        002
        003  import java.net.*;
        004  import java.io.*;
        005
        006  public class HttpSimulator
        007  {
        008      private Socket socket;
        009      private int port = 80;
        010      private String host = "localhost";
        011      private String request = ""; // HTTP請求消息
        012      private boolean isPost, isHead;
        013
        014      public void run() throws Exception
        015      {
        016          BufferedReader reader = new BufferedReader(new InputStreamReader(
        017                  System.in));
        018          while (true)  // 開始大循環
        019          {
        020              try
        021              {
        022                  if (!readHostAndPort(reader))
        023                      break;
        024                  readHttpRequest(reader);
        025                  sendHttpRequest();
        026                  readHttpResponse(reader);
        027              }
        028              catch (Exception e)
        029              {
        030                  System.out.println("err:" + e.getMessage());
        031              }
        032          }
        033      }
        034      public static void main(String[] args) throws Exception
        035      {
        036          new HttpSimulator().run();
        037      }
        038  }      從上面的代碼可以看出,第022、024、025和026分別調用了上述的四個方法。這些方法的具體實現將在后面討論。上面的代碼除了調用這四個核心方法外,還做了一些準備工作。在008至012行定義了一些以后要用到的變量。在016和017行使用控制臺的輸入流建立了BufferedReader對象,通過這個對象,可以直接從控制臺讀取字符串,而不是一個個地字節。
        二、readHostAndPort(……)方法的實現
        這個方法的主要功能是從控制臺讀取域名和端口。域名和端口通過":"隔開,":"和域名以及端口之間不能有空格。當從控制臺讀取一個"q"時,這個函數返回false,表示程序可以退出了,否則返回true,表示輸入的域名和端口是正確的。這個方法的實現代碼如下:
        001  private boolean readHostAndPort(BufferedReader consoleReader)
        002          throws Exception
        003  {
        004      System.out.print("host:port>");
        005      String[] ss = null;
        006      String s = consoleReader.readLine();
        007      if (s.equals("q"))
        008          return false;
        009      else
        010      {
        011          ss = s.split("[:]");
        012          if (!ss[0].equals(""))
        013              host = ss[0];
        014          if (ss.length > 1)
        015              port = Integer.parseInt(ss[1]);
        016          System.out.println(host + ":" + String.valueOf(port));
        017          return true;
        018      }
        019  }
        第001行:這個方法有一個BufferedReader類型的參數,這個參數的值就是在HttpSimulator.java中的第016和017行根據控制臺輸入流建立的BufferedReader對象。
        第 004 行:這輸出HTTP模擬器的控制符,就象Windows的控制臺的"C:">"一樣。
        第 006 行:從控制臺讀取一行字符串。
        第 011 行:通過字符串的split方法和響應的正則表示式("[:]")將域名和端口分開。域名的默認值是localhost,端口的默認值是80.
        三、readHttpRequest(……)方法的實現
        這個方法的主要功能是從控制臺讀取HTTP請求消息,如果輸入一個空行,表示請求消息頭已經輸完;如果使用的是POST方法,還要輸入POST請求的實體內容。這個方法的實現代碼如下:
        001  private void readHttpRequest(BufferedReader consoleReader)
        002          throws Exception
        003  {
        004      System.out.println("請輸入HTTP請求:");
        005      String s = consoleReader.readLine();
        006      request = s + "\r\n";
        007      boolean isPost = s.substring(0, 4).equals("POST");
        008      boolean isHead = s.substring(0, 4).equals("HEAD");
        009      while (!(s = consoleReader.readLine()).equals(""))
        010          request = request + s + "\r\n";
        011      request = request + "\r\n";
        012      if (isPost)
        013      {
        014          System.out.println("請輸入POST方法的內容:");
        015          s = consoleReader.readLine();
        016          request = request + s;
        017      }
        018  }
        第 005 行:讀入HTTP請求消息的第一行。
        第 007、008行:確定所輸入的請求方法是不是POST和HEAD.
        第 009、010行:讀入HTTP請求消息的其余行。
        第012 -017行:如果HTTP請求使用的是POST方法,要求用戶繼續輸入HTTP請求的實體內容。
        四、sendHttpRequest()方法的實現
        這個方法的功能是將request變量中的HTTP請求消息發送到服務器。下面是這個方法的實現代碼:
        001      private void sendHttpRequest() throws Exception
        002      {
        003          socket = new Socket();
        004          socket.setSoTimeout(10 * 1000);
        005          System.out.println("正在連接服務器");
        006          socket.connect(new InetSocketAddress(host, port), 10 * 1000);
        007          System.out.println("服務器連接成功!");
        008          OutputStream out = socket.getOutputStream();
        009          OutputStreamWriter writer = new OutputStreamWriter(out);
        010          writer.write(request);
        011          writer.flush();
        012      }
        第004行:設置讀取數據超時為10秒。
        第006行:連接服務器,并設置連接超時為10秒。     五、readHttpResponse(……)方法的實現
        這個方法的主要功能是從服務器讀取返回的響應消息。首先讀取了響應消息頭,然后要求用戶輸入Y或N以確定是否顯示響應消息的實體內容。這個程序之所以這樣做,主要有兩個原因:
        (1) 為了研究HTTP協議。
        (2) 由于本程序是以字符串形式顯示響應消息的,因此,如果用戶請求了一個二進制Web資源,如一個rar文件,那么實體內容將會顯示亂碼。所以在顯示完響應消息頭后由用戶決定是否顯示實體內容。
        這個方法的實現代碼如下:
        001  private void readHttpResponse(BufferedReader consoleReader)
        002  {
        003      String s = "";
        004      try
        005      {
        006          InputStream in = socket.getInputStream();
        007          InputStreamReader inReader = new InputStreamReader(in);
        008          BufferedReader socketReader = new BufferedReader(inReader);
        009          System.out.println("---------HTTP頭---------");
        010          boolean b = true; // true: 未讀取消息頭 false: 已經讀取消息頭
        011          while ((s = socketReader.readLine()) != null)
        012          {
        013              if (s.equals("") && b == true && !isHead)
        014              {
        015                  System.out.println("------------------------");
        016                  b = false;
        017                  System.out.print("是否顯示HTTP的內容(Y/N):");
        018                  String choice = consoleReader.readLine();
        019                  if (choice.equals("Y") || choice.equals("y"))
        020                  {
        021                      System.out.println("---------HTTP內容---------");
        022                      continue;
        023                  }
        024                  else
        025                      break;
        026              }
        027              else
        028                  System.out.println(s);
        029          }
        030      }
        031      catch (Exception e)
        032      {
        033          System.out.println("err:" + e.getMessage());
        034      }
        035      finally
        036      {
        037          try
        038          {
        039              socket.close();
        040          }
        041          catch (Exception e)
        042          {
        043          }
        044      }
        045      System.out.println("------------------------");
        046  }
        在上面的代碼中013行是最值得注意的。其中s.equals("")表示讀入一個空行(表明消息頭已經結束);由于在實體內容中也可以存在空行,因此,b == true來標記消息頭是否已經被讀過,當讀完消息頭后,將b設為false,如果以后再遇到空行,就不會當成消息頭來處理了。當HTTP請求使用HEAD方法時,服務器只返回響應消息頭;因此,使用!isHead來保證使用HEAD發送請求時不顯示響應消息的內容實體。
        現在我們已經實現了這個HTTP模擬器,下面讓我們來運行并測試它。
        運行
        運行如下的命令
        java http.HttpSimulator
        運行以上的命令后,將顯示如圖1所示的界面。

      
        圖1
        測試
        在HTTP模擬器中輸入如下的域名:
        www.csdn.net
        在HTTP模擬器中輸入如下的HTTP請求消息:
        GET / HTTP/1.1
        Host: www.csdn.net
        運行的結果如圖2所示。  


        本文實現的Http模擬器在后面的文章中會經常使用,讀者可以從本文的開始部分下載Http模擬器的源代碼和。class文件。
    本文地址:http://www.portaltwn.com/thread-61114-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    sw9518 發表于 2011-4-21 09:25:08
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • EtherCAT®和Microchip LAN925x從站控制器介紹培訓教程
    • MPLAB®模擬設計器——在線電源解決方案,加速設計
    • 讓您的模擬設計靈感,化為觸手可及的現實
    • 深度體驗Microchip自動輔助駕駛應用方案——2025巡展開啟報名!
    • 貿澤電子(Mouser)專區

    相關視頻

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷