> 那A有什么用啊,现直接提交给B不就行了有用啊,比如 B 所在的地方其它机器看不到,只有 A 能看到。
> 有没有具体实现的方法大家参考一下。这方面接触不多,也正好借机会学习一下。具体的实现是有的。我们公司在软件产品里实现了这样一个功能:用户使用我们的软件产品的时候,可以通过公网交换数据。这个功能本身很简单,只要软件运行的时候起一个服务器(其实就是一个 Tomcat),然后互相访问就可以了。问题在于,用户很可能是在一个私网中,它的 IP 在公网上是不可见的。如果只有一方不可见,另一方有合法的公网 IP 倒也罢了,如果双方都在私网中,怎么办?我们的处理方法是,在公网上架设一个公共服务器,用户(A)端的软件运行起来后,除了 Tomcat 之外,还要启动一个 X 进程,向公共服务器发起一个连接,并一直保持;公网服务器上有一个 Y 进程负责维护这些连接。当另一个用户(B)端程序要跟 A 端的程序联系的时候,实际上是跟 Y 进程联系,由 Y 进程负责转发给 X 进程,再由 X 进程转发给 Tomcat。相当于是把 A 用户的 Tomcat 服务发布给了 B 用户。因为我们是用 Socket 实现的通信转发,所以,事实上不止可以发布 Web 服务。我就试过用这个方法把用户上跑的 VNC Server 发布出来,这样我就可以通过 VNC Client 访问他的机器了,这在远程维护和培训指导的时候很有用。由于是公司的产品,我在这里能说的只有这些,不能提供源代码。如果你有什么疑问,我们可以在这里交流。
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();//接收的消息
}
}
1、A服务器建成中转服务器,启动ServerSocket做监听;
2、客户端向A服务器建立Socket,发送数据;
3、A服务器接受数据后向B服务器建立Socket,发送从客户端接受到的数据;
4、A服务器接受到B服务器返回的数据,返回给客户端。其实 A服务器就是一个中转服务器
它与客户端、B服务器之间通讯的协议
你自己可以界定
比如用UDP、HTTP等都可以
自己定各中间传输协议就ok了
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--------------------------------------------
> 研究谈论一下,看看还有没有别的好方法。我没有仔细看你的实现方法,不过单从设计思想上判断,我认为你这种方法可能不太合适,不符合你的“不解析直接转发”的初衷。既然你用 HTTP 方式对 request 进行了接收,无论如何,这已经是相当于做了“解析”了。不如从 Socket 层面来处理更直接。
maquan('ma:kju) 兄说的有道理,有没有具体实现的方法大家参考一下。这方面接触不多,也正好借机会学习一下。