public static void main(String[] args) throws IOException { ChannelRouter channelRouter = new ChannelRouter( new ExceptionListener<IOException>() { @Override public void exceptionThrown(IOException exception) { exception.printStackTrace(); } }); int port = Integer.parseInt(args[1]); SocketChannel socketChannel; if (args[0].equals("--server")) { System.out.println("Server mode started; listening on port " + port); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress(port)); socketChannel = serverSocketChannel.accept(); System.out.println("Client connected"); serverSocketChannel.close(); } else { String host = args[0]; System.out.println("Client mode started; connecting to " + host + " on port " + port); socketChannel = SocketChannel.open(new InetSocketAddress(host, port)); System.out.println("Connected to server"); } socketChannel.configureBlocking(false); Pipe localToRemote = Pipe.open(); localToRemote.source().configureBlocking(false); channelRouter.addRoute(localToRemote.source(), socketChannel); final Pipe remoteToLocal = Pipe.open(); remoteToLocal.sink().configureBlocking(false); channelRouter.addRoute(socketChannel, remoteToLocal.sink()); Thread channelRouterThread = new Thread(channelRouter, "ChannelRouter"); channelRouterThread.start(); Thread remoteReaderThread = new Thread("RemoteReader") { @Override public void run() { try { // BufferedReader.readLine() blocks until an end-of-line is // written, so make sure they get written by the main thread InputStream temporaryInputStream = Channels.newInputStream(remoteToLocal.source()); BufferedReader in = new BufferedReader(new InputStreamReader(temporaryInputStream)); String line = in.readLine(); while (null != line) { System.out.println(line); line = in.readLine(); } } catch (ClosedByInterruptException e) { // The main thread wants us to close, so do nothing } catch (IOException e) { e.printStackTrace(); } } }; remoteReaderThread.start(); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); Writer temporaryWriter = new OutputStreamWriter(Channels.newOutputStream(localToRemote.sink())); temporaryWriter = new BufferedWriter(temporaryWriter); PrintWriter out = new PrintWriter(temporaryWriter, true); System.out.println( "Press end-of-file to terminate (Ctrl+Z on Windows, Ctrl+D on other platforms)"); String line = in.readLine(); while (null != line) { // The end-of-line is required for BufferedReader.readLine() to // return and this will automatically flush due to the auto-flush // parameter on construction out.println(line); line = in.readLine(); } remoteReaderThread.interrupt(); channelRouterThread.interrupt(); socketChannel.close(); }