Article updated on

Java Simple Proxy Server con Sockets Ejemplo

Esto puede servir para:

  • Capturar el tráfico entre cliente y servidor
  • Limitar en ancho de banda o simular bajo ancho de banda.
  • Emular como se comporta el sistema si hay problemas con la red.
  • Modificar el contenido "en caliente" , etc.

* Los ejemplos no contienen esta funcionalidad puedes usarlos como base.  No siempre se pueden usar como HTTP proxies.

Ejemplo 1 (MultiSocket Proxy Server) 

Usar Ejemplo 1 como HTTP Proxy para otro HTTP Proxy

Ejemplo 2 (sólo un socket a la vez)

Ejemplo 2 HTTP Proxy

Ejemplo 1

import java.io.*;
import java.net.*;
/**
 *
 * @author jcgonzalez.com
 *
 */
public class ProxyMultiThread {
    public static void main(String[] args) {
        try {
            if (args.length != 3)
                throw new IllegalArgumentException("insuficient arguments");
            // and the local port that we listen for connections on
            String host = args[0];
            int remoteport = Integer.parseInt(args[1]);
            int localport = Integer.parseInt(args[2]);
            // Print a start-up message
            System.out.println("Starting proxy for " + host + ":" + remoteport
                    + " on port " + localport);
            ServerSocket server = new ServerSocket(localport);
            while (true) {
                new ThreadProxy(server.accept(), host, remoteport);
            }
        } catch (Exception e) {
            System.err.println(e);
            System.err.println("Usage: java ProxyMultiThread "
                    + "<host> <remoteport> <localport>");
        }
    }
}
/**
 * Handles a socket connection to the proxy server from the client and uses 2
 * threads to proxy between server and client
 *
 * @author jcgonzalez.com
 *
 */
class ThreadProxy extends Thread {
    private Socket sClient;
    private final String SERVER_URL;
    private final int SERVER_PORT;
    ThreadProxy(Socket sClient, String ServerUrl, int ServerPort) {
        this.SERVER_URL = ServerUrl;
        this.SERVER_PORT = ServerPort;
        this.sClient = sClient;
        this.start();
    }
    @Override
    public void run() {
        try {
            final byte[] request = new byte[1024];
            byte[] reply = new byte[4096];
            final InputStream inFromClient = sClient.getInputStream();
            final OutputStream outToClient = sClient.getOutputStream();
            Socket client = null, server = null;
            // connects a socket to the server
            try {
                server = new Socket(SERVER_URL, SERVER_PORT);
            } catch (IOException e) {
                PrintWriter out = new PrintWriter(new OutputStreamWriter(
                        outToClient));
                out.flush();
                throw new RuntimeException(e);
            }
            // a new thread to manage streams from server to client (DOWNLOAD)
            final InputStream inFromServer = server.getInputStream();
            final OutputStream outToServer = server.getOutputStream();
            // a new thread for uploading to the server
            new Thread() {
                public void run() {
                    int bytes_read;
                    try {
                        while ((bytes_read = inFromClient.read(request)) != -1) {
                            outToServer.write(request, 0, bytes_read);
                            outToServer.flush();
                            //TODO CREATE YOUR LOGIC HERE
                        }
                    } catch (IOException e) {
                    }
                    try {
                        outToServer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
            // current thread manages streams from server to client (DOWNLOAD)
            int bytes_read;
            try {
                while ((bytes_read = inFromServer.read(reply)) != -1) {
                    outToClient.write(reply, 0, bytes_read);
                    outToClient.flush();
                    //TODO CREATE YOUR LOGIC HERE
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (server != null)
                        server.close();
                    if (client != null)
                        client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            outToClient.close();
            sClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

Para compilar y usar:

javac ProxyMultiThread.java

java ProxyMultiThread 192.168.1.10 8080 9999

 Starting proxy for 192.168.1.10:8180 on port 9999

(Ahora el trafico se redirige de localhost 9999 a 192.168.1.10 a través del proxy. Los HTTP no siempre pueden funcionar.

 

Usar Ejemplo 1 como HTTP Proxy de otro HTTP Proxy

Si tu proxy es myproxy.test.net en el puerto 380 y quieres usar que pase por el código del ejemplo antes de que llege finalmente a tu proxy debes ejecutarlo así:

java ProxyMultiThread myproxy.test.net 80 9999

Ahora ajusta tu browser para que vaya por el proxy que esta en tu localhost en el puerto 9999

En firefox:

img/0/87/settings.png

* Ahora todo el tráfico va al ejemplo 1 antes de ir al proxy real

Ejemplo 2

// This example is from _Java Examples in a Nutshell_. (http://www.oreilly.com)
// Copyright (c) 1997 by David Flanagan
// This example is provided WITHOUT ANY WARRANTY either expressed or implied.
// You may study, use, modify, and distribute it for non-commercial purposes.
// For any commercial use, see http://www.davidflanagan.com/javaexamples
import java.io.*;
import java.net.*;
/**
 * This class implements a simple single-threaded proxy server.
 **/
public class SimpleProxyServer {
  /** The main method parses arguments and passes them to runServer */
  public static void main(String[] args) throws IOException {
    try {
      // Check the number of arguments
      if (args.length != 3)
        throw new IllegalArgumentException("Wrong number of arguments.");
      // Get the command-line arguments: the host and port we are proxy for
      // and the local port that we listen for connections on
      String host = args[0];
      int remoteport = Integer.parseInt(args[1]);
      int localport = Integer.parseInt(args[2]);
      // Print a start-up message
      System.out.println("Starting proxy for " + host + ":" + remoteport +
                         " on port " + localport);
      // And start running the server
      runServer(host, remoteport, localport);   // never returns
    }
    catch (Exception e) {
      System.err.println(e);
      System.err.println("Usage: java SimpleProxyServer " +
                         "<host> <remoteport> <localport>");
    }
  }
  /**
   * This method runs a single-threaded proxy server for
   * host:remoteport on the specified local port.  It never returns.
   **/
  public static void runServer(String host, int remoteport, int localport)
       throws IOException {
    // Create a ServerSocket to listen for connections with
    ServerSocket ss = new ServerSocket(localport);
    // Create buffers for client-to-server and server-to-client communication.
    // We make one final so it can be used in an anonymous class below.
    // Note the assumptions about the volume of traffic in each direction...
    final byte[] request = new byte[1024];
    byte[] reply = new byte[4096];
    // This is a server that never returns, so enter an infinite loop.
    while(true) {
      // Variables to hold the sockets to the client and to the server.
      Socket client = null, server = null;
      try {
        // Wait for a connection on the local port
        client = ss.accept();        
        // Get client streams.  Make them final so they can
        // be used in the anonymous thread below.
        final InputStream from_client = client.getInputStream();
        final OutputStream to_client= client.getOutputStream();
        // Make a connection to the real server
        // If we cannot connect to the server, send an error to the
        // client, disconnect, then continue waiting for another connection.
        try { server = new Socket(host, remoteport); }
        catch (IOException e) {
          PrintWriter out = new PrintWriter(new OutputStreamWriter(to_client));
          out.println("Proxy server cannot connect to " + host + ":" +
                      remoteport + ":\n" + e);
          out.flush();
          client.close();
          continue;
        }
        // Get server streams.
        final InputStream from_server = server.getInputStream();
        final OutputStream to_server = server.getOutputStream();
        // Make a thread to read the client's requests and pass them to the
        // server.  We have to use a separate thread because requests and
        // responses may be asynchronous.
        new Thread() {
          public void run() {
            int bytes_read;
            try {
              while((bytes_read = from_client.read(request)) != -1) {
                to_server.write(request, 0, bytes_read);
                System.out.println(bytes_read+"to_server--->"+ new String(request, "UTF-8")+"<---");
                to_server.flush();
              }
            }
            catch (IOException e) {}
            // the client closed the connection to us, so  close our
            // connection to the server.  This will also cause the
            // server-to-client loop in the main thread exit.
            try {to_server.close();} catch (IOException e) {}
          }
        }.start();
        // Meanwhile, in the main thread, read the server's responses
        // and pass them back to the client.  This will be done in
        // parallel with the client-to-server request thread above.
        int bytes_read;
        try {
          while((bytes_read = from_server.read(reply)) != -1) {
              try {
                    Thread.sleep(1);
                  System.out.println(bytes_read+"to_client--->"+ new String(request, "UTF-8")+"<---");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            to_client.write(reply, 0, bytes_read);
            to_client.flush();
          }
        }
        catch(IOException e) {}
        // The server closed its connection to us, so close our
        // connection to our client.  This will make the other thread exit.
        to_client.close();
      }
      catch (IOException e) { System.err.println(e); }
      // Close the sockets no matter what happens each time through the loop.
      finally {
        try {
          if (server != null) server.close();
          if (client != null) client.close();
        }
        catch(IOException e) {}
      }
    }//while(true)    
  }
}

 

Ejemplo 3 HTTP proxy

Este es un proyecto Open Source de un HTTP Java Proxy por Benjamin Kohl & Artem Melnik descarga aquí  o ve al lugar original aquí.