Cyh的博客

          Email:kissyan4916@163.com
          posts - 26, comments - 19, trackbacks - 0, articles - 220

          網(wǎng)絡(luò)編程>>代理服務(wù)器

          Posted on 2009-12-13 15:45 啥都寫點(diǎn) 閱讀(263) 評論(0)  編輯  收藏 所屬分類: J2SE
               本實(shí)例實(shí)現(xiàn)了一個(gè)代理服務(wù)器,實(shí)質(zhì)上是實(shí)現(xiàn)了一個(gè)代理服務(wù),部署在前文實(shí)現(xiàn)的通用服務(wù)器框架上。用戶需要指定目標(biāo)服務(wù)器的IP地址和端口,然后在瀏覽器中輸入本地網(wǎng)址,便可以訪問目標(biāo)服務(wù)器上的網(wǎng)頁。

                代理服務(wù)作為一個(gè)服務(wù)部署在服務(wù)器框架上,必須實(shí)現(xiàn)book.net.GeneraServer$Service接口,實(shí)現(xiàn)它的serve方法。
                當(dāng)客戶端請求代理服務(wù)時(shí),客戶端與代理服務(wù)之間會建立socket,代理服務(wù)收到請求后,會與目標(biāo)服務(wù)器建立Socket。
                代理服務(wù)持有兩個(gè)Socket,它起中轉(zhuǎn)作用,將來自客戶端的請求轉(zhuǎn)發(fā)給服務(wù)器,來自服務(wù)器端的響應(yīng)消息轉(zhuǎn)發(fā)給客戶端,可以通過兩個(gè)線程分別處理請求消息的轉(zhuǎn)發(fā)和響應(yīng)消息的轉(zhuǎn)發(fā)。


          import java.io.*;
          import java.net.*;

          /**
           * 本類為支持多線程服務(wù)器框架的GeneralServer類提供了一個(gè)相關(guān)的服務(wù)Service,
           * 使GeneralServer提供代理服務(wù)。內(nèi)部類ProxyService實(shí)現(xiàn)了GeneralServer.Service接口。
           *
          */

          public class ProxyServer {
              
          // 命令行的格式是:代理服務(wù)器連接的目標(biāo)服務(wù)器的域名、端口以及代理服務(wù)開啟的本地端口
              public static final String usage =  
                  
          "Usage: java book.net.ProxyServer <remotehost> <remoteport> <localport> ";
              
          /** 
               * 創(chuàng)建一個(gè)GeneralServer對象,并添加代理服務(wù)ProxyService對象到這個(gè)服務(wù)器上。
               *
          */

              
          public static void main(String[] args) {
                  
          try {
                      
          // 檢驗(yàn)參數(shù)
                      if ((args.length == 0|| (args.length % 3 != 0)){
                          
          throw new IllegalArgumentException("Wrong number of args");
                      }

                  
                      
          // 創(chuàng)建一個(gè)服務(wù)器:GeneralServer對象,用于管理服務(wù),
                      
          // 第一個(gè)參數(shù)為null表示服務(wù)器的日志輸出在標(biāo)準(zhǔn)輸出上,第二個(gè)參數(shù)12表示最大連接數(shù)
                      GeneralServer server = new GeneralServer(null12);
                  
                      
          // 從命令行中解析參數(shù),可以創(chuàng)建多個(gè)代理服務(wù)
                      int i = 0;
                      
          while(i < args.length) {
                          
          // 目標(biāo)服務(wù)器的域名和地址
                          String remotehost = args[i++];
                          
          int remoteport = Integer.parseInt(args[i++]);
                          
          // 代理服務(wù)在本地的端口
                          int localport = Integer.parseInt(args[i++]);
                          
          // 創(chuàng)建一個(gè)連接到目標(biāo)服務(wù)器的代理服務(wù)對象,并部署在本地服務(wù)器上的localport端口上。
                          server.addService(new ProxyService(remotehost, remoteport), localport);
                      }

                  }

                  
          catch (Exception e) {
                      System.err.println(e);
                      System.err.println(usage);
                      System.exit(
          1);
                  }

              }

              
              
          /**
               * 實(shí)現(xiàn)代理服務(wù)的功能,實(shí)現(xiàn)了GeneralServer.Service接口的serve方法。
               * 首先與目標(biāo)服務(wù)器建立連接,然后將來自客戶端的輸入流輸出到目標(biāo)服務(wù)器端,
               * 將來自目標(biāo)服務(wù)器的輸入流輸出到客戶端。
               * 輸入輸出流的流向控制是通過2個(gè)線程實(shí)現(xiàn)的。
               
          */

              
          public static class ProxyService implements GeneralServer.Service {
                  
          // 目標(biāo)服務(wù)器的域名和端口
                  String remotehost;
                  
          int remoteport;
              
                  
          /**
                   * 構(gòu)造方法
                   
          */

                  
          public ProxyService(String host, int port) {
                      
          this.remotehost = host;
                      
          this.remoteport = port;
                  }

              
                  
          /**
                   * 當(dāng)客戶端調(diào)用GeneralServer上的代理服務(wù)時(shí),將調(diào)用serve方法
                   
          */

                  
          public void serve(InputStream in, OutputStream out) {
                      
          // 來自客戶端的輸入流
                      final InputStream from_client = in;
                      
          // 輸出到客戶端的輸出流
                      final OutputStream to_client = out;
                      
          // 與目標(biāo)服務(wù)器的輸入輸出流
                      final InputStream from_server;
                      
          final OutputStream to_server;

                      
          // 連接到目標(biāo)服務(wù)器的socket對象
                      final Socket server;
                      
          try {
                          
          // 連接目標(biāo)服務(wù)器,初始化from_server,to_server流
                          server = new Socket(remotehost, remoteport);
                          from_server 
          = server.getInputStream();
                          to_server 
          = server.getOutputStream();
                      }
           catch (Exception e) {
                          
          // 如果連接失敗,則向客戶端發(fā)送失敗的消息
                          PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
                          pw.print(
          "Proxy server could not connect to " + remotehost
                                  
          + ":" + remoteport + "\n");
                          pw.flush();
                          pw.close();
                          
          try {
                              in.close();
                          }
           catch (IOException ex) {
                          }

                          
          return;
                      }

                  
                      
          // 創(chuàng)建一個(gè)線程,將來自客戶端的輸入流字節(jié)輸出到目標(biāo)服務(wù)器上
                      Thread client2server = new Thread() {
                          
          public void run() {
                              
          byte[] buffer = new byte[2048];
                              
          int bytes_read;
                              
          try {
                                  
          // 從來自客戶端的輸入流中讀取數(shù)據(jù),寫到目標(biāo)服務(wù)器上
                                  while ((bytes_read = from_client.read(buffer)) != -1{
                                      to_server.write(buffer, 
          0, bytes_read);
                                      to_server.flush();
                                  }

                              }
           catch (IOException e) {
                              }
           finally {
                                  
          // 當(dāng)線程結(jié)束時(shí),關(guān)閉與目標(biāo)服務(wù)器的socket連接和2個(gè)輸入輸出流
                                  try {
                                      server.close(); 
                                      to_client.close(); 
                                      from_client.close();
                                  }
           catch (IOException e) {
                                  }

                              }

                          }

                      }
          ;

                      
          // 創(chuàng)建一個(gè)線程,用于將來自目標(biāo)服務(wù)器的輸入流輸出到客戶端
                      Thread server2client = new Thread() {
                          
          public void run() {
                              
          byte[] buffer = new byte[2048];
                              
          int bytes_read;
                              
          try {
                                  
          // 讀取來自目標(biāo)服務(wù)器的輸入流from_server,然后輸出到to_client
                                  while ((bytes_read = from_server.read(buffer)) != -1{
                                      to_client.write(buffer, 
          0, bytes_read);
                                      to_client.flush();
                                  }

                              }
           catch (IOException e) {
                              }
           finally {
                                  
          try {
                                      server.close(); 
                                      to_client.close();
                                      from_client.close();
                                  }
           catch (IOException e) {
                                  }

                              }

                          }

                      }
          ;

                      
          // 啟動這兩個(gè)線程
                      client2server.start();
                      server2client.start();

                      
          // 當(dāng)這個(gè)兩個(gè)線程運(yùn)行結(jié)束時(shí),本次服務(wù)才結(jié)束
                      try {
                          client2server.join();
                          server2client.join();
                      }
           catch (InterruptedException e) {
                      }

                  }

              }

          }


                在命令行下輸入"java book.net.ProxyServer www.google.com 80 5555",將啟動代理服務(wù)器,端口為5555.打開瀏覽器,在地址欄中輸入' http://localhost:5555 " 將會打開www.google.com的主頁。


                                                                                                                 --    學(xué)海無涯
                  

          主站蜘蛛池模板: 通江县| 叙永县| 潮安县| 芜湖市| 瑞安市| 泰州市| 精河县| 平乐县| 龙岩市| 昔阳县| 佛坪县| 莱阳市| 和静县| 崇州市| 盐城市| 岑溪市| 香格里拉县| 甘谷县| 郑州市| 偏关县| 沛县| 菏泽市| 宁海县| 阿拉善盟| 邻水| 二手房| 金华市| 怀仁县| 左贡县| 南澳县| 磴口县| 定西市| 武冈市| 光泽县| 太保市| 周宁县| 拉孜县| 通河县| 古丈县| 荃湾区| 双城市|