Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/main/java/io/github/winroot33/ClientConnectionHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.github.winroot33;

import lombok.RequiredArgsConstructor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
* Класс для обработки соединений с клиентами, Runnable для передачи в пул потоков
*/
@RequiredArgsConstructor
public class ClientConnectionHandler implements Runnable {
private final Socket clientSocket;

@Override
public void run() {
handleConnection();
}

/**
* Обработка нового соединения
*/
private void handleConnection() {
try (Socket socket = this.clientSocket;
PrintWriter out = new PrintWriter(socket.getOutputStream(), true, StandardCharsets.UTF_8);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8))) {

processClientMessages(in, out);

} catch (IOException e) {
System.err.println("IO Error: " + e.getMessage());
}
}

/**
* Метод для отправки эхо сообщений пользователю
*
* @param in входной поток данных
* @param out выходной поток
*/
private void processClientMessages(BufferedReader in, PrintWriter out) throws IOException {
String inputLine;
while ((inputLine = in.readLine()) != null) {
out.println(inputLine);
System.out.printf("Thread: %s\tMessage sent: %s\n", Thread.currentThread().getName(), inputLine);
}
}
}
46 changes: 46 additions & 0 deletions src/main/java/io/github/winroot33/ConnectionExecutor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.github.winroot33;

import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
* Обертка над ExecutorService для удобного создания новых соединений с клиентами
*/
public class ConnectionExecutor {
private final ExecutorService threadPool;

/**
* Создание пула потоков с указанным количеством
*
* @param maxConnections количество потоков для FixedThreadPool
*/
public ConnectionExecutor(int maxConnections) {
this.threadPool = Executors.newFixedThreadPool(maxConnections);
}

/**
* Обработка подключения нового клиента, создание и отправка задачи в ExecutorService
*
* @param clientSocket сокет с соединением нового клиента
*/
public void executeConnection(Socket clientSocket) {
Runnable connectionHandler = new ClientConnectionHandler(clientSocket);
threadPool.execute(connectionHandler);
}

/**
* Корректная остановка пула потоков
*/
public void shutdownGracefully() {
threadPool.shutdown();
try {
if (!threadPool.awaitTermination(30, TimeUnit.SECONDS)) {
threadPool.shutdownNow();
}
} catch (InterruptedException e) {
threadPool.shutdownNow();
}
}
}
41 changes: 41 additions & 0 deletions src/main/java/io/github/winroot33/EchoServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.github.winroot33;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* Класс для запуска эхо сервера
*/
public class EchoServer {

private final ConnectionExecutor connectionExecutor;
private final int port;

/**
* Создание эхо сервера
*
* @param port номер порта для сервера
* @param maxConnections количество потоков для FixedThreadPool
*/
public EchoServer(int port, int maxConnections) {
this.port = port;
this.connectionExecutor = new ConnectionExecutor(maxConnections);
}

/**
* Запуск эхо сервера
*/
public void start() throws IOException {

try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server started");
while (true) {
Socket clientSocket = serverSocket.accept();
connectionExecutor.executeConnection(clientSocket);
}
} finally {
connectionExecutor.shutdownGracefully();
}
}
}
6 changes: 5 additions & 1 deletion src/main/java/io/github/winroot33/Main.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package io.github.winroot33;

import java.io.IOException;

public class Main {
public static void main(String[] args) {
public static void main(String[] args) throws IOException {
EchoServer server = new EchoServer(7, 10);
server.start();
}
}