Implements a TCP/IP bounce utility (proxy) : Utilities « Network Protocol « Java






Implements a TCP/IP bounce utility (proxy)

    
/**
 * The utillib library.
 * More information is available at http://www.jinchess.com/.
 * Copyright (C) 2002 Alexander Maryanovsky.
 * All rights reserved.
 *
 * The utillib library is free software; you can redistribute
 * it and/or modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * The utillib library is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with utillib library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


import java.io.*;
import java.net.Socket;
import java.net.ServerSocket;


/**
 * Implements a TCP/IP bounce utility (proxy). You run bounce specifying which
 * port to listen on, which host and on which port to connect to and it will
 * act as a proxy relaying information between anyone who connects to it and the
 * specified server.
 */

public class Bounce{


  
  /**
   * The main method.
   */

  public static void main(String [] args){
    if (args.length < 3){
      printUsage();
      System.exit(1);
    }

    int localPort;
    try{
      localPort = Integer.parseInt(args[0]);
    } catch (NumberFormatException e){
        System.err.println("Bad local port value: "+args[0]);
        printUsage();
        System.exit(2);
        return;
      }

    String hostname = args[1];

    int remotePort;
    try{
      remotePort = Integer.parseInt(args[2]);
    } catch (NumberFormatException e){
        System.err.println("Bad remote port value: "+args[2]);
        printUsage();
        System.exit(3);
        return;
      }

    boolean shouldLog = args.length > 3 ? Boolean.valueOf(args[3]).booleanValue() : false;
    int numConnections = 0;

    try{
      ServerSocket ssock = new ServerSocket(localPort);
      while (true){
        Socket incomingSock = ssock.accept();
        Socket outgoingSock = new Socket(hostname, remotePort);
        numConnections++;

        InputStream incomingIn = incomingSock.getInputStream();
        InputStream outgoingIn = outgoingSock.getInputStream();
        OutputStream incomingOut = incomingSock.getOutputStream();
        OutputStream outgoingOut = outgoingSock.getOutputStream();

        if (shouldLog){
          String incomingLogName = "in-log-"+incomingSock.getInetAddress().getHostName()+ "("+localPort+")-" + numConnections + ".dat";
          String outgoingLogName = "out-log-" + hostname + "("+remotePort + ")-" + numConnections+".dat";
          OutputStream incomingLog = new FileOutputStream(incomingLogName);
          incomingOut = new MultiOutputStream(incomingOut, incomingLog);
          OutputStream outgoingLog = new FileOutputStream(outgoingLogName);
          outgoingOut = new MultiOutputStream(outgoingOut, outgoingLog);
        }

        PumpThread t1 = new PumpThread(incomingIn, outgoingOut);
        PumpThread t2 = new PumpThread(outgoingIn, incomingOut);
        t1.start();
        t2.start();
      }
    } catch (IOException e){
        e.printStackTrace();
        System.exit(3);
      }
  }



  /**
   * Dumps usage information to the standard error stream.
   */

  private static void printUsage(){
    System.err.println("Bounce Utility");
    System.err.println("Copyright (C) 2002 Alexander Maryanovsky");
    System.err.println();
    System.err.println("Usage: java free.util.Bounce localPort hostname remotePort [shouldLog]");
    System.out.println();
    System.out.println("Version 1.01 - 31 Nov. 2002");
  }



}
/**
 * The utillib library.
 * More information is available at http://www.jinchess.com/.
 * Copyright (C) 2002 Alexander Maryanovsky.
 * All rights reserved.
 *
 * The utillib library is free software; you can redistribute
 * it and/or modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * The utillib library is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with utillib library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


/**
 * An <code>OutputStream</code> which relays all data written into it into a
 * list of given <code>OutputStreams</code>.
 */

class MultiOutputStream extends OutputStream{



  /**
   * An array containing the OutputStreams we're relaying data to.
   */

  private final OutputStream [] streams;



  /**
   * Creates a new <code>MultiOutputStream</code> which relays data to the
   * specified two <code>OutputStreams</code>. Any <code>null</code> values
   * will be silently ignored.
   */

  public MultiOutputStream(OutputStream out1, OutputStream out2){
    this(new OutputStream[]{out1, out2});
  }



  /**
   * Creates a new <code>MultiOutputStream</code> which relays data to the
   * specified <code>OutputStreams</code>. Any <code>null</code> items in the
   * array will be silently ignored.
   */

  public MultiOutputStream(OutputStream [] streams){
    if (streams == null)
      throw new IllegalArgumentException("Specified array may not be null");

    int count = 0;
    for (int i = 0; i < streams.length; i++)
      if (streams[i] != null)
        count++;

    this.streams = new OutputStream[count];
    count = 0;
    for (int i = 0; i < streams.length; i++){
      OutputStream stream = streams[i];
      if (stream != null)
        this.streams[count++] = stream;
    }
  }



  /**
   * Closes all the underlying <code>OutputStreams</code>.
   */

  public void close() throws IOException{
    for (int i = 0; i < streams.length; i++)
      streams[i].close();
  }



  /**
   * Flushes all the underlying <code>OutputStreams</code>.
   */

  public void flush() throws IOException{
    for (int i = 0; i < streams.length; i++)
      streams[i].flush();
  }




  /**
   * Writes the specified <code>byte</code> into the underlying
   * <code>OutputStreams</code>.
   */
  
  public void write(int b) throws IOException{
    for (int i = 0; i < streams.length; i++)
      streams[i].write(b);
  }




  /**
   * Writes the specified amount of bytes from the given byte array starting
   * at the specified offset to the underlying <code>OutputStreams</code>.
   */

  public void write(byte [] arr, int offset, int length) throws IOException{
    for (int i = 0; i < streams.length; i++)
      streams[i].write(arr, offset, length);
  }

}
/**
 * The utillib library.
 * More information is available at http://www.jinchess.com/.
 * Copyright (C) 2002 Alexander Maryanovsky.
 * All rights reserved.
 *
 * The utillib library is free software; you can redistribute
 * it and/or modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * The utillib library is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with utillib library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


/**
 * A thread which pumps information read from a given input stream into the
 * given output stream.
 */

 class PumpThread extends Thread{


  /**
   * The InputStream.
   */

  private final InputStream in;



  /**
   * The OutputStream.
   */

  private final OutputStream out;




  /**
   * The buffer we're using.
   */

  private final byte [] buffer;




  /**
   * The IOException thrown while reading or writing information, or null if
   * none.
   */

  private IOException exception;




  /**
   * Creates a new PumpThread which will pump information from the given
   * InputStream into the given OutputStream.
   */

  public PumpThread(InputStream in, OutputStream out){
    this(in, out, 2048);
  }




  /**
   * Creates a new PumpThread which will pump information from the given
   * InputStream into the given OutputStream and will use a buffer of the given
   * size.
   */

  public PumpThread(InputStream in, OutputStream out, int bufSize){
    this(in, out, new byte[bufSize]);
  }




  /**
   * Creates a new PumpThread which will pump information from the given
   * InputStream into the given OutputStream and will use the given buffer.
   */

  public PumpThread(InputStream in, OutputStream out, byte [] buffer){
    this.in = in;
    this.out = out;
    this.buffer = buffer;
  }




  /**
   * Does the actual pumping.
   */

  public void run(){
    try{
      while (true){
        int count = in.read(buffer);
        if (count <= 0)
          return;
        out.write(buffer, 0, count);
      }
    } catch (IOException e){
        exception = e;
      }
  }




  /**
   * Returns the exception thrown while reading or writing, or <code>null</code>
   * if it finished normally, without throwing an exception (read returned -1).
   *
   * @throws IllegalStateException if the thread is still alive.
   */

  public IOException getException(){
    if (isAlive())
      throw new IllegalStateException("The thread is still alive");

    return exception;
  }

}

   
    
    
    
  








Related examples in the same category

1.A class that encodes URL parameter values for MIDP devices.
2.Get the listing of everyone logged on
3.Scan your computer for ports in useScan your computer for ports in use
4.Using the URL Class (GetURL.java)
5.TCP socket monitor
6.Create Socket helper
7.URL utilities class that makes it easy to create new URLs based off of old URLs without having to assemble or parse them yourself
8.Download from URL
9.URL ParserURL Parser
10.A simple class to load an URL in a browser
11.Using the java API URL class, extract the http/https hostname.
12.Utility class for URL decoding.
13.Utility class for URL encoding.
14.Allows easy downloading of files from HTTP sites
15.enum Http Status