From e95655a4501980856e1c86a5570ebf94e6fdc77a Mon Sep 17 00:00:00 2001 From: csct3434 Date: Tue, 31 Dec 2024 14:21:17 +0900 Subject: [PATCH] =?UTF-8?q?Chapter.10=20=EB=AF=B8=EC=85=98B=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Mission B: Busy-Waiting Non-Blocking Server Co-authored-by: famo1245 --- chapter10/missionB/MissionB.java | 137 +++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 chapter10/missionB/MissionB.java diff --git a/chapter10/missionB/MissionB.java b/chapter10/missionB/MissionB.java new file mode 100644 index 0000000..8604c4b --- /dev/null +++ b/chapter10/missionB/MissionB.java @@ -0,0 +1,137 @@ +package chapter10.missionB; + +import java.io.IOException; +import java.io.InputStream; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class MissionB { + + public static void main(String[] args) { + Server server = new Server(); + server.start(); + } + + private static class Server { + + private static final int BUFFER_SIZE = 1024; + private static final String HOST = "127.0.0.1"; + private static final int PORT_NUM = 12345; + + private ServerSocket serverSocket; + private final Set clients = new HashSet<>(); + + public void start() { + try { + serverSocket = new ServerSocket(); + serverSocket.bind(new InetSocketAddress(HOST, PORT_NUM)); + serverSocket.setSoTimeout(200); + System.out.println("Server listening for incoming connections"); + + while (true) { + accept(); + serveAllClients(); + } + } catch (IOException e) { + System.err.println("Server error: " + e.getMessage()); + } finally { + closeServer(); + } + } + + private void closeServer() { + clients.forEach(SocketHandler::close); + clients.clear(); + + try { + if (serverSocket != null && !serverSocket.isClosed()) { + serverSocket.close(); + } + } catch (IOException e) { + System.err.println("Server error with closing: " + e.getMessage()); + } + System.out.println("Server stopped"); + } + + private void serveAllClients() { + Iterator iterator = clients.iterator(); + + while (iterator.hasNext()) { + SocketHandler client = iterator.next(); + if (!client.handle()) { + iterator.remove(); + client.close(); + } + } + } + + private void accept() { + try { + Socket client = serverSocket.accept(); + client.setSoTimeout(200); + clients.add(new SocketHandler(client)); + System.out.println("Connected to " + client.getRemoteSocketAddress()); + } catch (SocketTimeoutException ignored) { + } catch (IOException e) { + System.err.println("accept: " + e.getMessage()); + } + } + + private static class SocketHandler { + + private final Socket socket; + private final byte[] buffer; + + public SocketHandler(Socket socket) { + this.socket = socket; + buffer = new byte[BUFFER_SIZE]; + } + + public boolean handle() { + try { + InputStream in = socket.getInputStream(); + + if (in.available() > 0) { + int bytesRead = in.read(buffer); + + if (bytesRead == -1) { + return false; + } + + String message = new String(buffer, 0, bytesRead).trim(); + String response; + try { + int order = Integer.parseInt(message); + response = "Thank you for ordering " + order + " pizzas!\n"; + } catch (NumberFormatException e) { + response = "Wrong number of pizzas, please try again\n"; + } + + System.out.println("Sending message to " + socket.getRemoteSocketAddress()); + socket.getOutputStream().write(response.getBytes()); + } + return true; + } catch (IOException e) { + System.err.println("Socket error: " + e.getMessage()); + return false; + } + } + + public void close() { + try { + if (socket != null && !socket.isClosed()) { + System.out.println("Closing " + socket.getRemoteSocketAddress()); + socket.close(); + } + } catch (IOException e) { + System.err.println("Error with closing client connection: " + e.getMessage()); + } + } + } + } +}