diff --git a/README.md b/README.md index 8b98fdd..5c93871 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,36 @@ # SERVER : попытки настройки многофункционального сервера java ## Назначение +1. реализация exchange-сервиса + - работа с HTTP протоколом (браузерным клиентом) + - передача файлов от сервера в браузер + - получение файлов от браузера на сервер +2. реализация браузерного многопользовательского чата/форума +3. реализация движка для управления динамическим контентом (лекции/презентации/графики обучения/) +4. реализация движка для управения статическим контентом +5. реализация интерфейса работы с базой данных (moodle) + - заведение пользователей на платформу + - выгрузка результатов тестирования пользователей +6. реализация сервиса авторизации + - на сервере + - в сторонних приложениях +7. +## Реализация +### Конфигурация сервера +#### class Server +Конструкторы: +- Конструктор принимает номер порта, на котором запускется сервер +Методы: +start() +down() + +Запускает ServerSocket на порту PORT + + +> Сервер запускается в отдельном потоке, чтобы избежать блокирования приложения при реализации графического интерфейса. + + +> Каждое соединение (Connection) запускается в отдельном потоке, чтобы обеспечить возможность многопользовательской реализации клиентского приложения + +> Каждый stream (поток пердачи данных) запускается в отдельном потоке, чтобы обеспечить возможность одновременно передавать, получать данные, а также сообщать серверу консольные команды. + +### Разбор HTTP запросов diff --git a/content/exchange.http b/content/exchange.http new file mode 100644 index 0000000..f2f8e95 --- /dev/null +++ b/content/exchange.http @@ -0,0 +1,21 @@ +HTTP/1.1 200 OK + + + + + + + molokoin.ru + + +
+ molokoin.ru +
+
+
  • gitea
  • +
  • apache
  • +
  • exchange
  • +
  • hello
  • +
    + + \ No newline at end of file diff --git a/content/j130-lab1.pdf b/content/j130-lab1.pdf new file mode 100644 index 0000000..6fd587c Binary files /dev/null and b/content/j130-lab1.pdf differ diff --git a/content/sample.http b/content/sample.http new file mode 100644 index 0000000..b9d422b --- /dev/null +++ b/content/sample.http @@ -0,0 +1,23 @@ +HTTP/1.1 200 OK + + + + + send + + +
    +

    +

    +
    +
    + Download link + filename +
    + + + \ No newline at end of file diff --git a/src/main/docs/uml/class.puml b/src/main/docs/uml/class.puml new file mode 100644 index 0000000..82c454c --- /dev/null +++ b/src/main/docs/uml/class.puml @@ -0,0 +1,10 @@ +@startuml +title "Classes to: Server" +class Runner/'Инициализация и запуск компонентов программы'/ +class Face extends Server +class Server extends Thread +class Connection extends Thread +class ConsoleReader extends Thread +class InputReader extends Thread +class OutputWriter extends Thread +@enduml \ No newline at end of file diff --git a/src/main/docs/uml/sequence.puml b/src/main/docs/uml/sequence.puml new file mode 100644 index 0000000..aba8f7c --- /dev/null +++ b/src/main/docs/uml/sequence.puml @@ -0,0 +1,9 @@ +@startuml +title "Logic: Server" +participant "Клиент" as client +participant "Сервер" as server +client --> server : "запрос" +server --> server : "определение типа запроса\ntext, http ..." +server --> server : "инициация соответствующего\n режима работы с клиентом" +client <-- server : "ответ:\n- текст\n- http content\n- файл" +@enduml \ No newline at end of file diff --git a/src/main/docs/uml/usecase.puml b/src/main/docs/uml/usecase.puml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/ru/molokoin/Connection.java b/src/main/java/ru/molokoin/Connection.java new file mode 100644 index 0000000..56c5639 --- /dev/null +++ b/src/main/java/ru/molokoin/Connection.java @@ -0,0 +1,69 @@ +package ru.molokoin; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; +/** + * Класс рализующий обработку подключения клиента к серверу + * - Подключение вынесено в отдельный поток, чтобы обеспечить возможность подключения к серверу множества клиентов + */ +public class Connection extends Thread{ + public BufferedReader in; + public BufferedWriter out; + //public BufferedReader console; + + public Connection(Socket socket) throws IOException{ + System.out.println("Соединение с клиентом установлено ..."); + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + //console = new BufferedReader(new InputStreamReader(System.in)); + Thread threadConn = new Thread(this); + threadConn.start(); + } + + /** + * Запуск потоков: + * - получения сообщений, + * - отправки сообщений + */ + @Override + public void run(){ + //new InputReader(this).start();//Запустили нить чтения сообщений от клиента + Thread threadReader = new Thread(new InputReader(this)); + threadReader.start(); + //new OutputWriter(this).start();//Запуск нити записи ответа клиенту + Thread threadWriter = new Thread(new OutputWriter(this)); + threadWriter.start(); + //new ConsoleReader(this).start; консоль должна управлять всем сервером, а не отдельным подключением + + } + /** + * Отправка сообщений клиенту: + * - для отправки даты и времени получения сервером сообщения + * @param message + */ + public void send (String message){ + try { + out.write(message + "\n"); + out.flush(); + } catch (IOException e) { + System.out.println("Ошибка отправки сообщения: " + e.getMessage()); + } + } + /** + * Получение текущего времени на сервере + * @return + */ + public String getTime(){ + Date time; + SimpleDateFormat pattern; + time = new Date(); + pattern = new SimpleDateFormat("HH:mm:ss"); + return pattern.format(time); + } +} \ No newline at end of file diff --git a/src/main/java/ru/molokoin/ConsoleReader.java b/src/main/java/ru/molokoin/ConsoleReader.java new file mode 100644 index 0000000..c26f69a --- /dev/null +++ b/src/main/java/ru/molokoin/ConsoleReader.java @@ -0,0 +1,6 @@ +package ru.molokoin; + +public class ConsoleReader { + private Connection connection; + +} diff --git a/src/main/java/ru/molokoin/InputReader.java b/src/main/java/ru/molokoin/InputReader.java new file mode 100644 index 0000000..41d8713 --- /dev/null +++ b/src/main/java/ru/molokoin/InputReader.java @@ -0,0 +1,66 @@ +package ru.molokoin; + +import java.io.IOException; + +/** + * Нить чтения входящего от клиента потока данных + */ +public class InputReader extends Thread{ + static int index = 0;//порядковый номер обращения к серверу + private Connection connection; + public InputReader(Connection connection){ + this.connection = connection; + } + @Override + public void run(){ + String line; + + Boolean f = true; + try { + while (!connection.in.ready()) ; + index++; + System.out.println("Номер запроса: " + index); + StringBuilder header = new StringBuilder(); + StringBuilder body = new StringBuilder(); + Boolean isHeader = true; + //Boolean isBody = false; + while (connection.in.ready()) { + line = connection.in.readLine(); // ждем сообщения с сервера + if(isHeader){ + if (line != null){ + header.append(line); + System.out.println("header: " + line); + }else { + isHeader = false; + //isBody = true; + } + } + if(!isHeader){ + if (line != null){ + body.append(line); + System.out.println("body: " + line); + } + } + + /** + * тут происходит: + * - анализ поступающих от клиента сообщений + * - инициация событий (методов), запрошенных клиентом + */ + + + + // if (line.equals("stop")) { + // connection.down(); // харакири + // break; // выходим из цикла если пришло "stop" + // } + } + + + } catch (IOException | NullPointerException e) { + //connection.down(); + System.out.println("InputReader() : Ошибка получения сообщения: " + e.getMessage()); + } + } + +} diff --git a/src/main/java/ru/molokoin/OutputWriter.java b/src/main/java/ru/molokoin/OutputWriter.java new file mode 100644 index 0000000..2e27a6b --- /dev/null +++ b/src/main/java/ru/molokoin/OutputWriter.java @@ -0,0 +1,54 @@ +package ru.molokoin; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; + +/** + * Обработка передачи данных клиенту + */ +public class OutputWriter extends Thread{ + private Connection connection; + public OutputWriter(Connection connection){ + this.connection = connection; + } + @Override + public void run(){ + //чтение из файла, формирование сообщения для клиента + //String message = ""; + try (FileInputStream fileInputStream = new FileInputStream("C:\\Users\\devuser\\Documents\\code\\Server\\content\\sample.http")) { + BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 10); + int i; + while((i = bufferedInputStream.read())!= -1){ + char c = (char)i; + connection.out.write(c); + connection.out.flush(); + String s = Character.toString(c); + + + //message = message + (char)i; + } + } catch (IOException e) { + e.printStackTrace(); + } + //send(message); + // while(true){ + + //System.out.println("message: " + message); + //send(message); + // } + + } + /** + * Отправка подготовленного сообщения-строки + * @param message + */ + public void send (String message){ + try { + connection.out.write(message + "\n"); + connection.out.flush(); + } catch (IOException e) { + System.out.println("Ошибка отправки сообщения: " + e.getMessage()); + } + } +} diff --git a/src/main/java/ru/molokoin/Runner.java b/src/main/java/ru/molokoin/Runner.java deleted file mode 100644 index cc99714..0000000 --- a/src/main/java/ru/molokoin/Runner.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.molokoin; - -public class Runner { - public static void main(String[] args) { - System.out.println("Запущен основной поток приложения: " + Thread.currentThread().getName()); - } -} diff --git a/src/main/java/ru/molokoin/Server.java b/src/main/java/ru/molokoin/Server.java new file mode 100644 index 0000000..98703d3 --- /dev/null +++ b/src/main/java/ru/molokoin/Server.java @@ -0,0 +1,50 @@ +package ru.molokoin; +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.LinkedList; + +/** + * реализация основного потока сервера + * - сервер вынесен в самостоятельный поток, чтобы не прерывать работу интерфейса + */ +public class Server extends Thread{ + private int port; + private ServerSocket serverSocket; + private LinkedList connections = new LinkedList(); + + public Server(int port){ + this.port = port; + } + public static void main(String[] args) { + new Server(10001).run(); + } + + @Override + public void run() { + try (ServerSocket ss = new ServerSocket(port)) { + serverSocket = ss; + System.out.println("Сервер запущен ..."); + while (true){ + System.out.println("Сервер ожидает подключение клиента ..."); + Socket socket = serverSocket.accept(); + connections.add(new Connection(socket)); + } + } catch (IOException e) { + System.out.println("Запуск сервера не удался ..."); + System.out.println("Сообщение об ошибке: " + e.getMessage()); + } + } + /** + * Остановка работы сервера + */ + public void down(){ + /** + * В каждом соединении (connection) вызвать метод down() + * - закрыть потоки in/out + * - закрыть сокет подключения socket.close() + * закрыть сервер + * - serverSocket.close() + */ + } +} \ No newline at end of file diff --git a/src/main/java/ru/molokoin/faces/console/Face.java b/src/main/java/ru/molokoin/faces/console/Face.java new file mode 100644 index 0000000..563a58c --- /dev/null +++ b/src/main/java/ru/molokoin/faces/console/Face.java @@ -0,0 +1,67 @@ +package ru.molokoin.faces.console; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import ru.molokoin.Server; +/** + * Нить консольного интерфейса + */ +public class Face extends Thread{ + private Server server; + private BufferedReader console; // поток чтения с консоли + + public Face(Server server){ + System.out.println("Инициализация консольного интерфейса управления сервером ..."); + console = new BufferedReader(new InputStreamReader(System.in)); + this.server = server; + } + @Override + public void run(){ + System.out.println("Запуск консольного интерфейса управления сервером ..."); + hello(); + } + private void hello() { + System.out.println("Консольный интерфейс управления сервером запущен."); + System.out.println(">>> СВЕДЕНИЯ О ПРОГРАММЕ <<<"); + System.out.println("Для вызова помощи введите команду: \\help"); + System.out.println("----------------------------"); + help(); + } + private void help(){ + System.out.println("Перечень доступных команд:"); + System.out.println("перечень доступных команд: \\help"); + System.out.println("запуск сервера: \\start"); + System.out.println("остановка сервера: \\stop"); + System.out.println("сводка по работе сервера: \\status"); + listen(); + } + private void listen(){ + System.out.println("Для получения помощи введите \\help"); + System.out.println("Введите команду серверу:"); + + try{ + String s = console.readLine(); + switch (s) { + case ("\\start"): + Thread serverThread = new Thread(server); + serverThread.start(); + listen(); + break; + case ("\\stop"): + server.down(); + break; + case ("\\quit"): + System.exit(1); + break; + default: + System.out.println("Указана не верная команда, попробуйте еще раз ..."); + listen(); + break; + } + }catch(IOException e){ + System.out.println("Ошибка listen() чтения с консоли: " + e.getMessage()); + } + } +} diff --git a/target/classes/ru/molokoin/Connection.class b/target/classes/ru/molokoin/Connection.class new file mode 100644 index 0000000..8936f8c Binary files /dev/null and b/target/classes/ru/molokoin/Connection.class differ diff --git a/target/classes/ru/molokoin/ConsoleReader.class b/target/classes/ru/molokoin/ConsoleReader.class new file mode 100644 index 0000000..4007369 Binary files /dev/null and b/target/classes/ru/molokoin/ConsoleReader.class differ diff --git a/target/classes/ru/molokoin/InputReader.class b/target/classes/ru/molokoin/InputReader.class new file mode 100644 index 0000000..200dc2d Binary files /dev/null and b/target/classes/ru/molokoin/InputReader.class differ diff --git a/target/classes/ru/molokoin/OutputWriter.class b/target/classes/ru/molokoin/OutputWriter.class new file mode 100644 index 0000000..f6e979a Binary files /dev/null and b/target/classes/ru/molokoin/OutputWriter.class differ diff --git a/target/classes/ru/molokoin/Runner.class b/target/classes/ru/molokoin/Runner.class deleted file mode 100644 index 087a9ed..0000000 Binary files a/target/classes/ru/molokoin/Runner.class and /dev/null differ diff --git a/target/classes/ru/molokoin/Server.class b/target/classes/ru/molokoin/Server.class new file mode 100644 index 0000000..6c6db02 Binary files /dev/null and b/target/classes/ru/molokoin/Server.class differ diff --git a/target/classes/ru/molokoin/faces/console/Face.class b/target/classes/ru/molokoin/faces/console/Face.class new file mode 100644 index 0000000..ccbdfb1 Binary files /dev/null and b/target/classes/ru/molokoin/faces/console/Face.class differ