+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;
+ }
+}