import javax.imageio.*; import java.awt.image.*; import java.awt.event.*; import java.awt.*; import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; import java.lang.reflect.*; import java.net.*; import java.io.*; import javax.swing.text.*; import javax.swing.event.*; import javax.swing.*; import java.util.concurrent.atomic.*; import java.util.concurrent.*; import java.util.regex.*; import java.util.List; import java.util.zip.*; import java.util.*; public class main { public static void main(String[] args) throws Exception { answerQuestionsOnPortAndConsole(new StringFunc() { public String get(String s) { try { return "You said: " + reverseString(s) ; } catch (Exception _e) { throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } } }); } static abstract class DialogIO { abstract boolean isStillConnected(); abstract String readLineNoBlock(); abstract boolean waitForLine(); abstract void sendLine(String line); abstract boolean isLocalConnection(); abstract Socket getSocket(); } static abstract class DialogHandler { abstract void run(DialogIO io); } // Dialog classes static int answerQuestions_defaultPort = 5000; static void answerQuestionsOnPort(final StringFunc f) { answerQuestionsOnPort(answerQuestions_defaultPort, f); } static void answerQuestionsOnPort(int port, final StringFunc f) { startDialogServer(port, new DialogHandler() { public void run(final DialogIO io) { String dialogID = randomID(8); io.sendLine("Your ID: " + dialogID); while (io.isStillConnected()) { if (io.waitForLine()) { String line = io.readLineNoBlock(); String s = dialogID + " at " + now() + ": " + quote(line); print(s); if ("bye".equals(line)) { io.sendLine("bye stranger"); return; } String answer = answerQuestions_getAnswer(line, f); io.sendLine(answer == null ? "null" : answer); //appendToLog(logFile, s); } } }}); } static String answerQuestions_getAnswer(String line, StringFunc f) { String answer; try { answer = f.get(line); } catch (Throwable e) { e.printStackTrace(); answer = e.toString(); } print("! " + answer); return answer; } static void answerQuestionsOnPortAndConsole(final StringFunc f) { answerQuestionsOnPortAndConsole(answerQuestions_defaultPort, f); } static void answerQuestionsOnPortAndConsole(int port, final StringFunc f) { answerQuestionsOnPort(port, f); print("You may also type on this console."); String line; while ((line = readLine()) != null) { if ("bye".equals(line)) print("! bye stranger"); else answerQuestions_getAnswer(line, f); // prints answer on console too } } static String reverseString(String s) { return new StringBuilder(s).reverse().toString(); } static BufferedReader readLine_reader; static String readLine() { try { if (readLine_reader == null) readLine_reader = new BufferedReader(new InputStreamReader(System.in, "UTF-8")); String s = readLine_reader.readLine(); if (s != null) print(s); return s; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static AtomicInteger dialogServer_clients = new AtomicInteger(); static void startDialogServer(int port, DialogHandler handler) { if (!startDialogServerIfPortAvailable(port, handler)) fail("Can't start dialog server on port " + port); } // true on server set up, false on port not available // now uses "thread" and not "daemon" (keeps VM alive!) static boolean startDialogServerIfPortAvailable(int port, final DialogHandler handler) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(port); } catch (IOException e) { // probably the port number is used - let's assume there already is a chat server. return false; } final ServerSocket _serverSocket = serverSocket; Thread _t_0 = new Thread() { public void run() { try { while (true) { try { final Socket s = _serverSocket.accept(); print("connect - clients: " + dialogServer_clients.incrementAndGet()); Thread _t_1 = new Thread() { public void run() { try { try { final Writer w = new OutputStreamWriter(s.getOutputStream(), "UTF-8"); final BufferedReader in = new BufferedReader( new InputStreamReader(s.getInputStream(), "UTF-8")); DialogIO io = new DialogIO() { String line; boolean buff; Socket getSocket() { return s; } // local means localhost - todo: test boolean isLocalConnection() { return s.getInetAddress().isLoopbackAddress(); } boolean isStillConnected() { return !(buff || s.isClosed()); } String readLineNoBlock() { String l = line; line = null; return l; } boolean waitForLine() { try { if (line != null) return true; //print("Readline"); line = in.readLine(); //print("Readline done: " + line); if (line == null) buff = true; return line != null; } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} void sendLine(String line) { try { w.write(line + "\n"); w.flush(); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} }; try { handler.run(io); } finally { s.close(); } } finally { print("client disconnect - " + dialogServer_clients.decrementAndGet() + " remaining"); } } catch (Exception _e) { throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } } }; _t_1.start(); } catch (SocketTimeoutException e) { } } } catch (Exception _e) { throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } } }; _t_0.start(); print("Dialog server on port " + port + " started."); return true; } static String randomID(int length) { return makeRandomID(length); } static long now_virtualTime; static long now() { return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis(); } static void print() { System.out.println(); } static void print(Object o) { System.out.println(o); } static void print(long i) { System.out.println(i); } public static String quote(String s) { if (s == null) return "null"; return "\"" + s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\""; } static RuntimeException fail() { throw new RuntimeException("fail"); } static RuntimeException fail(String msg) { throw new RuntimeException(msg); } static String makeRandomID(int length) { Random random = new Random(); char[] id = new char[length]; for (int i = 0; i< id.length; i++) id[i] = (char) ((int) 'a' + random.nextInt(26)); return new String(id); } } interface StringFunc { String get(String s); }