public synchronized void closeConnections() {
        try {
            serverSocket.close();
        } catch (Exception e) {
        }
        try {
            clientSocket.close();
        } catch (Exception e) {
        }

        if (enableForwarding) {
            System.out.println("TCPForward between " +
                    clientSocket.getInetAddress().getHostAddress()
                    + ":" + clientSocket.getPort() + " and " +
                    serverSocket.getInetAddress().getHostAddress()
                    + ":" + serverSocket.getPort() + " stopped.");
            enableForwarding = false;
        }
    }
}

/*Manages the TCP forwarding between a source input stream and destination output stream
the input stream is read and forwarded to the output stream  */
class ForwardThread extends Thread {
    private static final int BUFFER_SIZE = 8192;

    InputStream inputStream;
    OutputStream outputStream;
    ClientThread parentThread;

    //constructor
    public ForwardThread(ClientThread parent, InputStream
            inStream, OutputStream outStream) {
        parentThread = parent;
        inputStream = inStream;
        outputStream = outStream;
    }

    //reads input stream and writes to the output stream
    public void run() {
        byte[] buffer = new byte[BUFFER_SIZE];
        try {
            while (true) {
                int bytesRead = inputStream.read(buffer);
                if (bytesRead == -1)
                    // end of stream is reached + exit loop
                    break;
                outputStream.write(buffer, 0, bytesRead);
                outputStream.flush();
            }
        } catch (IOException e) {
            // e.printStackTrace();
        }

        // notify parent if the connection is broken for some reason
        parentThread.closeConnections();
    }