esoe 2 years ago
parent
commit
694e6235f9
  1. 34
      README.md
  2. 21
      content/exchange.http
  3. BIN
      content/j130-lab1.pdf
  4. 23
      content/sample.http
  5. 10
      src/main/docs/uml/class.puml
  6. 9
      src/main/docs/uml/sequence.puml
  7. 0
      src/main/docs/uml/usecase.puml
  8. 69
      src/main/java/ru/molokoin/Connection.java
  9. 6
      src/main/java/ru/molokoin/ConsoleReader.java
  10. 66
      src/main/java/ru/molokoin/InputReader.java
  11. 54
      src/main/java/ru/molokoin/OutputWriter.java
  12. 7
      src/main/java/ru/molokoin/Runner.java
  13. 50
      src/main/java/ru/molokoin/Server.java
  14. 67
      src/main/java/ru/molokoin/faces/console/Face.java
  15. BIN
      target/classes/ru/molokoin/Connection.class
  16. BIN
      target/classes/ru/molokoin/ConsoleReader.class
  17. BIN
      target/classes/ru/molokoin/InputReader.class
  18. BIN
      target/classes/ru/molokoin/OutputWriter.class
  19. BIN
      target/classes/ru/molokoin/Runner.class
  20. BIN
      target/classes/ru/molokoin/Server.class
  21. BIN
      target/classes/ru/molokoin/faces/console/Face.class

34
README.md

@ -1,2 +1,36 @@ @@ -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 запросов

21
content/exchange.http

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
HTTP/1.1 200 OK
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>molokoin.ru</title>
</head>
<body>
<div class="header">
molokoin.ru
</div>
<div class="controls01">
<li><a href="http://molokoin.ru:3000/esoe">gitea</a></li>
<li><a href="http://www.molokoin.ru:8080">apache</a></li>
<li><a href="http://www.molokoin.ru/exchange">exchange</a></li>
<li><a href="http://www.molokoin.ru/hello">hello</a></li>
</div>
</body>
</html>

BIN
content/j130-lab1.pdf

Binary file not shown.

23
content/sample.http

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
HTTP/1.1 200 OK
<html>
<head>
<meta charset="utf-8">
<title>send</title>
</head>
<body>
<form enctype="multipart/form-data" method="post">
<p><input type="file" name="f">
<input type="submit" value="push"></p>
</form>
<div class="downloads">
<a href="content\j130-lab1.pdf" download="j130-lab1.pdf">Download link + filename</a>
</div>
<div class="links">
<li><a href="http://molokoin.ru:3000/esoe">gitea</a></li>
<li><a href="http://www.molokoin.ru:8080">apache</a></li>
<li><a href="http://www.molokoin.ru/exchange">exchange</a></li>
<li><a href="http://www.molokoin.ru/hello">hello</a></li>
</div>
</body>
</html>

10
src/main/docs/uml/class.puml

@ -0,0 +1,10 @@ @@ -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

9
src/main/docs/uml/sequence.puml

@ -0,0 +1,9 @@ @@ -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

0
src/main/docs/uml/usecase.puml

69
src/main/java/ru/molokoin/Connection.java

@ -0,0 +1,69 @@ @@ -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);
}
}

6
src/main/java/ru/molokoin/ConsoleReader.java

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
package ru.molokoin;
public class ConsoleReader {
private Connection connection;
}

66
src/main/java/ru/molokoin/InputReader.java

@ -0,0 +1,66 @@ @@ -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());
}
}
}

54
src/main/java/ru/molokoin/OutputWriter.java

@ -0,0 +1,54 @@ @@ -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());
}
}
}

7
src/main/java/ru/molokoin/Runner.java

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
package ru.molokoin;
public class Runner {
public static void main(String[] args) {
System.out.println("Запущен основной поток приложения: " + Thread.currentThread().getName());
}
}

50
src/main/java/ru/molokoin/Server.java

@ -0,0 +1,50 @@ @@ -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<Connection> connections = new LinkedList<Connection>();
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()
*/
}
}

67
src/main/java/ru/molokoin/faces/console/Face.java

@ -0,0 +1,67 @@ @@ -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());
}
}
}

BIN
target/classes/ru/molokoin/Connection.class

Binary file not shown.

BIN
target/classes/ru/molokoin/ConsoleReader.class

Binary file not shown.

BIN
target/classes/ru/molokoin/InputReader.class

Binary file not shown.

BIN
target/classes/ru/molokoin/OutputWriter.class

Binary file not shown.

BIN
target/classes/ru/molokoin/Runner.class

Binary file not shown.

BIN
target/classes/ru/molokoin/Server.class

Binary file not shown.

BIN
target/classes/ru/molokoin/faces/console/Face.class

Binary file not shown.
Loading…
Cancel
Save