代碼
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
public class NAT extends Thread {
private final Socket socket;
private final InetSocketAddress target;
public NAT(Socket socket, InetSocketAddress target) {
this.socket = socket;
this.target = target;
}
@Override
public void run() {
InputStream in = null, targetIn = null;
OutputStream out = null, targetOut = null;
Socket targetSocket = null;
try {
log("proxy %s to %s", socket.getInetAddress(),target);
in = socket.getInputStream();
out = socket.getOutputStream();
targetSocket = new Socket(target.getAddress(), target.getPort());
targetIn = targetSocket.getInputStream();
targetOut = targetSocket.getOutputStream();
CountDownLatch latch = new CountDownLatch(1);
transfer(latch, in, targetOut);
transfer(latch, targetIn, out);
latch.await();
} catch (Exception ignored) {
} finally {
closeIo(in);
closeIo(out);
closeIo(targetIn);
closeIo(targetOut);
closeIo(socket);
closeIo(targetSocket);
}
}
private static String LOG_FORMATTER = "%1$tF %1$tT %2$-3s %3$s%n";
private static void log(String message, Object... args) {
Date dat = new Date();
message = null == message ? " " : message;
String data = args.length > 0 ? String.format(message, args) : message;
Thread curr = Thread.currentThread();
String msg = String.format(LOG_FORMATTER, dat, curr.getId(), data, curr.getName());
System.out.print(msg);
}
/**
* 數據交換.主要用於tcp協議的交換
*
* @createTime 2014年12月13日 下午11:06:47
* @param lock
* 鎖
* @param in
* 輸入流
* @param out
* 輸出流
*/
public static void transfer(final CountDownLatch latch, final InputStream in, final OutputStream out) {
new Thread() {
public void run() {
byte[] bytes = new byte[1024];
int n;
try {
while ((n = in.read(bytes)) > 0) {
out.write(bytes, 0, n);
out.flush();
}
} catch (Exception ignored) {
}
if (null != latch) {
latch.countDown();
}
};
}.start();
}
private void closeIo(Closeable closeable) {
if (null != closeable) {
try {
closeable.close();
} catch (IOException ignored) {
}
}
}
public static void main(String[] args) throws IOException {
String tmp = args.length > 0 ? args[0] : "53";
int port = Integer.valueOf(tmp);
tmp = args.length > 1 ? args[1] : "127.0.0.1";
String targetHost = tmp;
tmp = args.length > 1 ? args[2] : "1053";
int targetPort = Integer.valueOf(tmp);
log("proxy %s to %s:%s", port,targetHost,targetPort);
InetSocketAddress net = new InetSocketAddress(targetHost, targetPort);
ServerSocket sso = new ServerSocket(port);
Socket socket = null;
while (null != (socket = sso.accept())) {
new NAT(socket, net).start();
}
sso.close();
}
}