近来,发现有不少端口映射的工具都挺好用的。突来一份好奇心,想了解一下里面的原理。所以想用Java写一个(不管效率如何,最主要的想明白其中的原理)。仔细考虑了一下,感觉应该用到Socket技术。但是问题出来了:“socket应该如何将一个进入端口的数据,转发之另一个端口——暂且先考虑一台机器的情况,比如从9663转到9664”。起初,先考虑的是Http协议的数据传输,由于Http传输的全都是以纯文本形势传输的,所以利用InputStream和OutputStream加以字符类型的转换(用到的Socket模拟Head提交在这里就不废话了),应该很容易能是实现(但是目前还没有测试成功,似乎在哪个方面除了什么猫腻,郁闷死了……)。但是这仅仅是以Http纯文本形势传过来的数据。我看了很多端口映射工具,映射得端口不仅仅能实现Http协议的映射,而是能将这些进入规定数据(不管是什么协议的)都能原原本本的转到另一个端口上,如果是这样的话,架设我有一个C/S结构的程序,同样能通过这个工具进行映射。数据不会发生任何错误。我同样尝试过利用二进制形势(byte[]数组)传输数据,但是也没有成功。以下是以byte[]数组传递数据的代码,我现在脑子短路了,一点思路也没有。到了while循环就停住了,也不发生循环,也不妨下继续(9090为本机Tomcat端口):
package sailing;
import java.io.*;
import java.net.*;
public class BinaryPort implements Runnable
{
private ServerSocket listenerSocket;
private Socket serverSocket;
private Socket tomcatSocket;
private Thread myThread;
private DataInputStream in;
private DataOutputStream out;
private ByteArrayOutputStream swapStream;
public BinaryPort()
{
try
{
System.out.println("Server is starting ..................");
this.listenerSocket=new ServerSocket(9961);
this.tomcatSocket=new Socket("127.0.0.1",9090);
this.swapStream=new ByteArrayOutputStream();
this.myThread=new Thread(this);
this.myThread.start();
}
catch(Exception e)
{
System.out.println(e);
}
}
public void run()
{
while(true)
{
try
{
this.serverSocket=this.listenerSocket.accept();
this.in=new DataInputStream(this.serverSocket.getInputStream());
byte[] buf=new byte[100];
int rc=0;
while((rc=in.read(buf,0,buf.length))!=-1)
{
this.swapStream.write(buf,0,rc);
this.swapStream.flush();
}
byte[] resBuf=swapStream.toByteArray();
this.out=new DataOutputStream(this.tomcatSocket.getOutputStream());
this.out.write(resBuf,0,resBuf.length);
this.out.flush();
//Get The Tomcat Web Server reBack Information
this.in=new DataInputStream(this.tomcatSocket.getInputStream());
byte[] buf2=new byte[100];
int rc2=0;
this.swapStream=null;
while((rc2=in.read(buf2,0,buf2.length))>0)
{
this.swapStream.write(buf2,0,rc2);
this.swapStream.flush();
rc2=0;
}
byte[] resBuf2=swapStream.toByteArray();
this.out=new DataOutputStream(this.serverSocket.getOutputStream());
this.out.write(resBuf2,0,resBuf2.length);
this.out.flush();
this.myThread.sleep(1000);
this.out.close();
this.in.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
}
public static void main(String args[])
{
new BinaryPort();
}
}

解决方案 »

  1.   

    while((rc=in.read(buf,0,buf.length))!=-1)
    你确定可行吗?
      

  2.   

    这个while循环,在起初能读取一些数据。但是到了输入流的末尾阶段就停滞不动了~~~~~~不知道你说的这个“可行”指的是什么?
      

  3.   

    看看这个两个类吧,不明白再问我
    import java.net.*;
    import java.io.*;
    // 这个是服务器端程序public class myServer
    {
    // 设定服务程序端口号,大于1024
    public static final int PORT = 8080;
    public static void main(String[] args)
       throws IOException
    {
    ServerSocket s = new ServerSocket(PORT);
    System.out.println("Started:"+s);
    try{
     Socket socket = s.accept();
     try{
       System.out.println("连接被接受"+socket);
       BufferedReader in =
        new BufferedReader(new InputStreamReader(socket.getInputStream()));
       PrintWriter out = 
        new PrintWriter(
         new BufferedWriter(
         new OutputStreamWriter(socket.getOutputStream())),true);
       while(true){
         String str = in.readLine()+ " 你要发送的信息";
         if(str.endsWith("END")) break;
         System.out.println("Echoing: "+str);
         out.println(str);
        } 
       }
       catch(Exception e)
        { System.out.println(e.toString());}
     finally{
        System.out.println("closing ...");
        socket.close();
      }
    }
    finally{
     s.close();
    }
    }
    }
    下面是客户端类
    mport java.net.*;
    import java.io.*;
    public class myClient
    {
    public static void main(String[] args) 
                          throws Exception
    {
    //
    // õip
    InetAddress addr = InetAddress.getByName("192.168.0.1");
    // ǵЧ
    // InetAddress addr = InetAddress.getByName("localhost");
    // InetAddress addr = InetAddress.getByName("127.0.0.1");
    System.out.println("ipַ:"+addr);
    // ͷһsocket
    Socket socket = new Socket(addr, myServer.PORT);
    try{
    System.out.println("׽(socket) = " + socket +"OK");
    BufferedReader in = 
        new BufferedReader(new InputStreamReader(socket.getInputStream()));
    PrintWriter out =
       new PrintWriter(
        new BufferedWriter(
         new OutputStreamWriter(socket.getOutputStream())),true);
     for(int i=0; i<10; i++){
       out.println(""+i);
       String str = in.readLine();
       System.out.println(str);
     }
     out.println("END");
    }

    catch(IOException e){
     System.out.println(e.toString());
    }

    finally{
      System.out.println("closing...");
      socket.close();
    }
    }
    }
      

  4.   

    这……这两个类我明白啊~~~~~~很简单啊~~~~~~~~~~~~~~~~`基于文本的传输我会啊~~~我这里出现的问题是Socket的二进制传输。这两个虽然有关系,但是关系不大吧~~~~~
      

  5.   

    package sailing;
    import java.io.*;
    import java.net.*;
    public class ModifyBinaryPort
    {
    private ServerSocket listenerSocket;
    private Socket serverSocket;
    public ModifyBinaryPort()
    {
    try
    {
    System.out.println("Server is starting ..................");
    this.listenerSocket=new ServerSocket(9633);
    while(true)
    {
    try
    {
    this.serverSocket=this.listenerSocket.accept();
    new MyThread(serverSocket).start();
    }
    catch(Exception e)
    {
    System.out.println(e);
    }
    }
    }
    catch(Exception e)
    {
    System.out.println(e);
    }
    }
    public static void main(String args[])
    {
    new ModifyBinaryPort();
    }
    class MyThread extends Thread
    {
    private Socket threadSocket;
    private Socket tomcatSocket;
    private Thread myThread;
    private DataInputStream in;
    private DataOutputStream out;
    public MyThread(Socket socket)
    {
    try
    {
    threadSocket=socket;
    this.tomcatSocket=new Socket("127.0.0.1",9090);
    }
    catch(Exception e)
    {
    System.out.println(e);
    }
    }
    public void run()
    {
    try
    {
    //Read Thread
    new ReadClientWriteTomcatThread(threadSocket,tomcatSocket).start();
    }
    catch(Exception e)
    {
    System.out.println(e);
    }
    }
    }
    class ReadClientWriteTomcatThread extends Thread
    {
    private DataInputStream read;
    private DataOutputStream write;
    private ByteArrayOutputStream swapStream;
    private Socket threadSocket;
    private Socket tomcatSocket;
    public ReadClientWriteTomcatThread(Socket threadSocketT,Socket tomcatSocketT)
    {
    try
    {
    threadSocket=threadSocketT;
    tomcatSocket=tomcatSocketT;
    read=new DataInputStream(threadSocket.getInputStream());
    write=new DataOutputStream(tomcatSocket.getOutputStream());
    this.swapStream=new ByteArrayOutputStream();
    }
    catch(Exception e)
    {
    System.out.println(e);
    }
    }
    public void run()
    {
    try
    {
    byte[] buf=new byte[100];
    int rc=0;
    while((rc=read.read(buf,0,buf.length))>0)
    {
    this.swapStream.write(buf,0,rc);
    this.swapStream.flush();
    if(rc<buf.length)
    {
    break;
    }
    //System.out.println(rc);
    }
    byte[] resBuf=swapStream.toByteArray();
    this.write.write(resBuf,0,resBuf.length);
    this.write.flush();
    //Reading the result from tomcat
    new ReadTomcatWriteClientThread(threadSocket,tomcatSocket).start();

    }
    catch(Exception e)
    {
    System.out.println(e);
    }
    }
    }
    class ReadTomcatWriteClientThread extends Thread
    {
    private DataInputStream read;
    private DataOutputStream write;
    private ByteArrayOutputStream swapStream;
    public ReadTomcatWriteClientThread(Socket threadSocket,Socket tomcatSocket)
    {
    try
    {
    read=new DataInputStream(tomcatSocket.getInputStream());
    write=new DataOutputStream(threadSocket.getOutputStream());
    this.swapStream=new ByteArrayOutputStream();
    }
    catch(Exception e)
    {
    System.out.println(e);
    }
    }
    public void run()
    {
    try
    {
    byte[] buf2=new byte[100];
    int rc2=0;
    while((rc2=read.read(buf2,0,buf2.length))>0)
    {
    this.swapStream.write(buf2,0,rc2);
    this.swapStream.flush();
    if(rc2<buf2.length)
    {
    break;
    }
    }
    byte[] resBuf2=swapStream.toByteArray();
    this.write=new DataOutputStream(write);
    this.write.write(resBuf2,0,resBuf2.length);
    this.write.flush();
    this.write.close();
    this.read.close();
    }
    catch(Exception e)
    {
    System.out.println(e);
    }
    }
    }
    }