0

我需要编写一个快速简便的端口转发器。目前它接受连接并且可以很好地从客户端读取,但是它没有从它运行的本地机器上得到任何东西。(仅供参考,这是为了转发网络服务器,因为我找不到我通常用来将 VS2010/2012 转发到网络的应用程序,所以我自己制作了)。

我知道吞咽异常,这很糟糕,但现在这并不重要,我可以稍后处理。

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

public class SocketForward {
  int src = 0;
  int dest = 0;
  public static void main(String args[]) throws Exception {
    if (args.length < 2) {
      System.out.println("Usage: java SocketForward <source port> <destination port>");
      System.exit(1);
    } else {
      new SocketForward().startRun(Integer.parseInt(args[0]), Integer.parseInt(args[1]));
    }
  }
  public void startRun(int src, int dest) throws Exception {
    try {
      this.src = src;
      this.dest = dest;
    } catch (NumberFormatException e) {
      System.out.println("Usage: java SocketForward <source port> <destination port>");
      System.exit(1);
    }
    ServerSocket server = new ServerSocket(dest);
    System.out.println("Waiting for connections...");
    while (!server.isClosed()) {
      new ConnHandler(src, server.accept());
    }
  }
}

class ConnHandler implements Runnable {
  Socket clientSocket;
  Socket hostSocket;
  int hostport;
  Thread thread;
  BufferedOutputStream hostOut;
  BufferedOutputStream clientOut;
  BufferedInputStream hostIn;
  BufferedInputStream clientIn;
  public ConnHandler(int hostport, Socket clientSocket) {
    System.out.println("Connected to " + clientSocket.getInetAddress());
    this.clientSocket = clientSocket;
    this.hostport = hostport;
    this.thread = new Thread(this);
    thread.start();
  }
  @Override
  public void run() {
    try {
      hostSocket = new Socket("", hostport);
      System.out.println("Connected to localhost:" + hostport);
      hostOut = new BufferedOutputStream(hostSocket.getOutputStream());
      clientOut = new BufferedOutputStream(clientSocket.getOutputStream());
      hostIn = new BufferedInputStream(hostSocket.getInputStream());
      clientIn = new BufferedInputStream(clientSocket.getInputStream());
      new Thread() {
        public void run() {
          while (this == Thread.currentThread()) {
            byte[] buf = new byte[8192];
            try {
              int len = 0;
              while ((len = ConnHandler.this.clientIn.read(buf)) > 0) {
                System.out.println("Client: " + new String(buf, 0, len));
                ConnHandler.this.hostOut.write(buf, 0, len);
              }
            } catch (Exception e) {
              e.printStackTrace();
              break;
            }
          }
        }
      }.start();
      new Thread() {
        public void run() {
          while (this == Thread.currentThread()) {
            byte[] buf = new byte[8192];
            try {
              int len = 0;
              while ((len = ConnHandler.this.hostIn.read(buf)) > 0) {
                System.out.println("Host: " + new String(buf, 0, len));
                ConnHandler.this.clientOut.write(buf, 0, len);
              }
            } catch (Exception e) {
              e.printStackTrace();
              break;
            }
          }
        }
      }.start();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
4

1 回答 1

0

您没有进行任何刷新,从而引入了不透明的中间人行为。这很可能会扰乱客户端和服务器所期望的数据流。

关于代码风格的旁注:try-catch在循环之外更方便while,所以它会自动中断:

try {
  while (...) ...
} catch (Throwable t) {
   t.printStackTrace();
}

还要注意Throwable,而不是——Exception你会想知道任何破坏你的代码的错误,而不仅仅是Exceptions。

于 2013-01-18T11:58:34.310 回答