package org.wamblee.socketproxy; /* * Created on Apr 5, 2005 */ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * @author erik * * TODO To change the template for this generated type comment go to Window - * Preferences - Java - Code Style - Code Templates */ public class SocketProxy { public static void main( final String[] args ) throws IOException { for ( int i = 0; i < args.length; i++ ) { // System.out.println(i + " " + args[i]); String[] fields = args[i].split( ":" ); final int localPort = Integer.parseInt( fields[0] ); final String host = fields[1]; final int remotePort = Integer.parseInt( fields[2] ); runSocketProxy( localPort, host, remotePort ); } } /** * @param localPort * @param host * @param remotePort */ private static void runSocketProxy( final int localPort, final String host, final int remotePort ) { new Thread( new Runnable( ) { public void run( ) { try { new SocketProxy( localPort, host, remotePort ); } catch ( IOException e ) { System.out.println( "Problem with socket " + localPort + ":" + host + ":" + remotePort ); e.printStackTrace( ); } } } ).start( ); } public SocketProxy( int localPort, String remoteHost, int remotePort ) throws IOException { System.out.println( "Listening on port " + localPort ); ServerSocket server = new ServerSocket( localPort ); for ( ;; ) { Socket socket = server.accept( ); System.out.println( "Got local connection on port " + localPort ); InputStream localIs = socket.getInputStream( ); OutputStream localOs = socket.getOutputStream( ); Socket clientSocket = new Socket( remoteHost, remotePort ); final String description = "Port forwarding: " + localPort + " -> " + remoteHost + ":" + remotePort; System.out.println( description + " established." ); InputStream serverIs = clientSocket.getInputStream( ); OutputStream serverOs = clientSocket.getOutputStream( ); Barrier barrier = new Barrier(2); final Thread t1 = runForwarder( barrier, "> ", localIs, serverOs ); final Thread t2 = runForwarder( barrier, "< ", serverIs, localOs ); waitForConnectionClose( description, t1, t2 ); } } /** * @param description * @param t1 * @param t2 */ private void waitForConnectionClose( final String description, final Thread t1, final Thread t2 ) { new Thread( new Runnable( ) { public void run( ) { try { t1.join( ); t2.join( ); } catch ( InterruptedException e ) { e.printStackTrace( ); } System.out.println( description + " closed" ); } } ).start( ); } private Thread runForwarder( final Barrier barrier, final String prefix, final InputStream is, final OutputStream os ) { Thread t = new ForwarderThread(prefix, barrier, is, os); t.start( ); return t; } }