public class IOCharacterShiftServer { private final char shift = 1; private final static String POISON_CODE = "#POISON"; private AtomicInteger poisonPills = new AtomicInteger(0); public void start(int threadsAmount, int clientsAmount, int port) throws Exception { try (ServerSocket listener = new ServerSocket(port)) { listener.setSoTimeout(100); ExecutorService pool = Executors.newFixedThreadPool(threadsAmount); while (poisonPills.get() < clientsAmount) { try { pool.execute(new LettersShifter(listener.accept())); } catch (SocketTimeoutException ex) { } } } } private class LettersShifter implements Runnable { private Socket socket; LettersShifter(Socket socket) { this.socket = socket; } @Override public void run() { try { Scanner in = new Scanner(socket.getInputStream()); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); while (in.hasNextLine()) { String nextLine = in.nextLine(); if (nextLine.equals(POISON_CODE)) { poisonPills.getAndAdd(1); break; } out.println(shift(nextLine)); } } catch (Exception e) { System.out.println("Error:" + socket); } finally { try { socket.close(); } catch (IOException e) { } System.out.println("Closed: " + socket); } System.out.println("Exit: " + socket); } private String shift(String str) { StringBuilder afterShift = new StringBuilder(); for (char ch : str.toCharArray()) { char shifted = (char) (ch + shift); if (shifted > 'z') { afterShift.append((char) (ch + shift - (26 - shift))); } else { afterShift.append(shifted); } } return afterShift.toString(); } } }