Fast implementation of a port forward in Java

Daniel picture Daniel · Oct 17, 2010 · Viewed 16.5k times · Source

I have build a simple application that opens a ServerSocket, and on connection, it connects itself to another server socket on a remote machine. To implement port forwarding, I use two threads, one that reads from the local inputstream and streams to the remote sockets outputstream, and vice versa.

The implementation feels a bit inperformant, and so I ask you if you know a better implementation strategy, or even have some code lying around to achive this in a performant way.

PS: I know I could use IPTables on Linux, but this has to work on Windows.

PPS: If you post implementations for this simple task, I will create a benchmark to test all given implementations. The solution should be fast for many small (~100bytes) packages and steady data streams.

My current implementation is this (executed on each of the two threads for each direction):

public static void route(InputStream inputStream, OutputStream outputStream) throws IOException {
    byte[] buffer = new byte[65536];
    while( true ) {
        // Read one byte to block
        int b = inputStream.read();
        if( b == - 1 ) {
            log.info("No data available anymore. Closing stream.");
            inputStream.close();
            outputStream.close();
            return;
        }
        buffer[0] = (byte)b;
        // Read remaining available bytes
        b = inputStream.read(buffer, 1, Math.min(inputStream.available(), 65535));
        if( b == - 1 ) {
            log.info("No data available anymore. Closing stream.");
            inputStream.close();
            outputStream.close();
            return;
        }
        outputStream.write(buffer, 0, b+1);
    }
}

Answer

Bozho picture Bozho · Oct 17, 2010

Take a look at tcpmon. Its purpose is to monitor tcp data, but it also forwards to a different host/port.

And here is some code for port forwarding taken from a book (it's not in English, so I'm pasting the code rather than giving a link to the book e-version):