import java.net.*; import java.io.*; /* Эхо-сервер. Все символы которые приходят от клиента, отправляются клиенту обратно. В командной строке можно указать порт сервера. По умолчанию - 12345 Компиляция: javac MultithreadServer.java Запуск: java MultithreadServer 12345 При запуске в командной строке полезно использовать: -Djava.net.preferIPv4Stack=true */ class MultithreadServer { // Порт по умолчанию final static String DEF_PORT = "12345"; /** * Точка входа в программу * @param argv Массив параметров командной строки */ public static void main(String argv[]) throws Exception { MultithreadServer instance = new MultithreadServer( argv.length>0 ? argv[1] : DEF_PORT ); instance.loop(); } // Серверный сокет ServerSocket sock; /** * Конструктор класса. Создаётся слушающий сокет * @param port Номер порта сервера */ MultithreadServer(String port) throws IOException { sock = new ServerSocket(Integer.parseInt(port)); } /** * Основной цикл сервера. Принимается запрос от клиента, * для каждого клиента создаётся экземпляр класса Client, * (т.е. фактически нить для обработки) */ void loop() throws IOException { do { new Client(sock.accept()); } while (true); } // Дочерний класс, хранящий контекст каждого клиента class Client implements Runnable { final Socket sock; final Thread th; /** * Конструктор класса. Создаётся новая нить для оперций ввода-вывода * @param sock Клиентский сокет */ Client(Socket sock) { this.sock = sock; System.out.println(sock.toString() + " connected"); th = new Thread(this); th.start(); } /** * Тело нити, обслуживающей операции ввода-вывода */ public void run() { try { InputStream istream = sock.getInputStream(); OutputStream ostream = sock.getOutputStream(); do { int data = istream.read(); if (data < 0) break; System.out.printf("%s read %c\n", sock.toString(), data); ostream.write((byte)data); } while (true); } catch (Exception e) { System.out.println(sock.toString() + " caught exception: " + e.getMessage()); } try { sock.close(); } catch (Exception e) {;} System.out.println(sock.toString() + " closed"); } } }