现在的要求是:由客户端传给A服务器一个请求,A需要把这个请求转给B服务器;B处理完成后把结果返回给A,A收到后再返回给客户端。最好能不要A来解析请求的内容,直接把信息包转交,象代理那样。
我目前没什么头绪,大家来讨论一下。

解决方案 »

  1.   

    UDP,先实现没代理的,再实现代理的~~代理机器当做服务器(HTTP +URL+SOCKET) 转发资源
      

  2.   

    我自己这不是没头绪吗。想看看大家有没有什么头绪。如果直接把request对象转发应该不行吧?如果把收到的request对象包装一下再发给B大家看行不行?lixiaoxue85(蛮野蛮)兄,讲些步骤来实践一下。这样说太空泛了。
      

  3.   

    socket应该能实现啊,最好发的消息用xml封装
    ajax有和方法和这个很类似
    function executeXhr(callback, url) {
      // branch for native XMLHttpRequest object
      if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = callback;
        req.open("GET", url, true); // 服务器url
        req.send(null);//发消息
      } // branch for IE/Windows ActiveX version
      else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
          req.onreadystatechange = callback;
          req.open("GET", url, true);
          req.send();//接收的消息
        }
      }
      

  4.   

    转发的内容是什么,UDP包、HTTP请求、ftp等等。针对不同的协议实现可以不一样的。
      

  5.   

    如果利用Socket和ServerSocket:
    1、A服务器建成中转服务器,启动ServerSocket做监听;
    2、客户端向A服务器建立Socket,发送数据;
    3、A服务器接受数据后向B服务器建立Socket,发送从客户端接受到的数据;
    4、A服务器接受到B服务器返回的数据,返回给客户端。其实 A服务器就是一个中转服务器
    它与客户端、B服务器之间通讯的协议
    你自己可以界定
    比如用UDP、HTTP等都可以
      

  6.   

    emin_lee()  写的很好了,不过具体细化方案还要研究。
      

  7.   

    > 信息包提交是可以用这种方式,接收到后如何做到不解析直接转发这才是关键。不太明白楼主的意思,能不能讲一下你觉得“不解析直接转发”的难点在哪里?我觉得,无非就是做一个这样的程序:一方面,它是一个服务器,用 ServerSocket 等待连接,并接收连接、接收数据;另一方面,它是一个客户端,可以用 Socket 向另外一个服务器发起连接,传送数据。每当它从 ServerSocket 得到连接请求(下游连接),就创建一个新的 Socket 向服务器发起一个连接(上游连接),并根据连接是否成功来决定是否接受下游连接;每当它从下游连接里收到数据,就发送到上游连接;同样,如果从上游连接收到发回来的数据,就转发到下游连接里面去;如果发现下游连接断开了,就去切断上游连接;同样,如果发现上游连接断开了,就去切点下游连接。也就这些喽……
      

  8.   

    lz不是已经很清晰了么
    自己定各中间传输协议就ok了
      

  9.   

    昨天整理了一下头绪,算是把转发的功能给实现了。大家有兴趣可以研究谈论一下,看看还有没有别的好方法。----------华丽的分割线-START--------------------------------------------
    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.io.*;
    import java.util.*;
    import java.net.*;public class TransmitPot
        extends HttpServlet {
      private static final String CONTENT_TYPE = "text/html; charset=GBK";  //Initialize global variables
      public void init() throws ServletException {
      }  public void service(HttpServletRequest request, HttpServletResponse response) throws
          IOException {
        response.setContentType(CONTENT_TYPE);
        //System.out.println("-----" + request.getMethod() + "-----");
        //System.out.println();
        String strUrl = "http://localhost:8080/WebApp/OfficeServer"; //转发的接收页面,这里是一个Servlet    try {
          URL objUrl = new URL(strUrl);
          HttpURLConnection urlConn = (HttpURLConnection) objUrl.openConnection(); //创建HttpURLConnection连接类
          urlConn.setRequestMethod("POST"); //使用POST方法提交
          urlConn.setDoOutput(true);
          OutputStream outStream = urlConn.getOutputStream(); //创建转发信息用的输出流
          byte[] mStream = ReadPackage(request); //获得需要转发的数据
          outStream.write(mStream); //将数据传给输出流
          outStream.flush(); //转发
          outStream.close(); //关闭输出流      //System.out.println(urlConn.getResponseMessage()); //返回信息      //取出返回数据
          InputStream ins2 = urlConn.getInputStream(); //获取返回的数据流
          byte[] mStream2 = getBytes(ins2); //使用二进制临时保存
          ins2.read(mStream2);
          SendPackage(response, mStream2); //将数据通过response返回
          ins2.close();
        }
        catch (Exception ex) {
          System.out.println(ex.getMessage());
          System.out.println("Transport data error!");
        }
      }  //取得客户端发来的数据包
      private byte[] ReadPackage(HttpServletRequest request) {
        byte mStream[] = null;
        int totalRead = 0;
        int readBytes = 0;
        int totalBytes = 0;
        try {
          totalBytes = request.getContentLength();
          mStream = new byte[totalBytes];
          while (totalRead < totalBytes) {
            request.getInputStream();
            readBytes = request.getInputStream().read(mStream, totalRead,
                                                      totalBytes - totalRead);
            totalRead += readBytes;
            continue;
          }
        }
        catch (Exception e) {
          System.out.println(e.toString());
        }
        return (mStream);
      }  //发送处理后的数据包
      private void SendPackage(HttpServletResponse response, byte[] mStream) {
        try {
          ServletOutputStream OutBinarry = response.getOutputStream();
          OutBinarry.write(mStream);
          OutBinarry.flush();
          OutBinarry.close();
        }
        catch (IOException e) {
          System.out.println(e.toString());
        }
      }  //将流转成byte[]
      public static byte[] getBytes(InputStream is) throws Exception {
        byte[] data = null;    Collection chunks = new ArrayList();
        byte[] buffer = new byte[1024 * 1000];
        int read = -1;
        int size = 0;    while ( (read = is.read(buffer)) != -1) {
          if (read > 0) {
            byte[] chunk = new byte[read];
            System.arraycopy(buffer, 0, chunk, 0, read);
            chunks.add(chunk);
            size += chunk.length;
          }
        }    if (size > 0) {
          ByteArrayOutputStream bos = null;
          try {
            bos = new ByteArrayOutputStream(size);
            for (Iterator itr = chunks.iterator(); itr.hasNext(); ) {
              byte[] chunk = (byte[]) itr.next();
              bos.write(chunk);
            }
            data = bos.toByteArray();
          }
          finally {
            if (bos != null) {
              bos.close();
            }
          }
        }
        return data;
      }
    }
    ----------华丽的分割线-END--------------------------------------------
      

  10.   

    用的方法其实还是很简单,直接用了HttpURLConnection类,把request数据内容部分进行转发。
      

  11.   

    > 昨天整理了一下头绪,算是把转发的功能给实现了。大家有兴趣可以
    > 研究谈论一下,看看还有没有别的好方法。我没有仔细看你的实现方法,不过单从设计思想上判断,我认为你这种方法可能不太合适,不符合你的“不解析直接转发”的初衷。既然你用 HTTP 方式对 request 进行了接收,无论如何,这已经是相当于做了“解析”了。不如从 Socket 层面来处理更直接。
      

  12.   

    我没有仔细看你的实现方法,不过单从设计思想上判断,我认为你这种方法可能不太合适,不符合你的“不解析直接转发”的初衷。既然你用 HTTP 方式对 request 进行了接收,无论如何,这已经是相当于做了“解析”了。不如从 Socket 层面来处理更直接。-------------------------------------------------------
    maquan('ma:kju) 兄说的有道理,有没有具体实现的方法大家参考一下。这方面接触不多,也正好借机会学习一下。
      

  13.   

    > 那A有什么用啊,现直接提交给B不就行了有用啊,比如 B 所在的地方其它机器看不到,只有 A 能看到。
      

  14.   

    > 有没有具体实现的方法大家参考一下。这方面接触不多,也正好借机会学习一下。具体的实现是有的。我们公司在软件产品里实现了这样一个功能:用户使用我们的软件产品的时候,可以通过公网交换数据。这个功能本身很简单,只要软件运行的时候起一个服务器(其实就是一个 Tomcat),然后互相访问就可以了。问题在于,用户很可能是在一个私网中,它的 IP 在公网上是不可见的。如果只有一方不可见,另一方有合法的公网 IP 倒也罢了,如果双方都在私网中,怎么办?我们的处理方法是,在公网上架设一个公共服务器,用户(A)端的软件运行起来后,除了 Tomcat 之外,还要启动一个 X 进程,向公共服务器发起一个连接,并一直保持;公网服务器上有一个 Y 进程负责维护这些连接。当另一个用户(B)端程序要跟 A 端的程序联系的时候,实际上是跟 Y 进程联系,由 Y 进程负责转发给 X 进程,再由 X 进程转发给 Tomcat。相当于是把 A 用户的 Tomcat 服务发布给了 B 用户。因为我们是用 Socket 实现的通信转发,所以,事实上不止可以发布 Web 服务。我就试过用这个方法把用户上跑的 VNC Server 发布出来,这样我就可以通过 VNC Client 访问他的机器了,这在远程维护和培训指导的时候很有用。由于是公司的产品,我在这里能说的只有这些,不能提供源代码。如果你有什么疑问,我们可以在这里交流。