From bc7f057327680818e607b40e5500d8de55c4b5a9 Mon Sep 17 00:00:00 2001 From: csct3434 Date: Sat, 28 Dec 2024 22:30:51 +0900 Subject: [PATCH] =?UTF-8?q?Chapter.10=20=EB=AF=B8=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= 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/README.md | 102 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/chapter10/README.md b/chapter10/README.md index 5e3f576..eb8abef 100644 --- a/chapter10/README.md +++ b/chapter10/README.md @@ -99,3 +99,105 @@ Wrong number of pizzas, please try again 12 Thank you for ordering 12 pizzas! ``` + +# Mission B: Busy-waiting non-blocking server +### Description +Implement the Python code below in Java + +### Python Code +```python +#!/usr/bin/env python3.9 + +"""Busy-waiting non-blocking server implementation""" + +import typing as T +from socket import socket, create_server + +# the maximum amount of data to be received at once +BUFFER_SIZE = 1024 +ADDRESS = ("127.0.0.1", 12345) # address and port of the host machine + + +class Server: + clients: T.Set[socket] = set() + + def __init__(self) -> None: + try: + print(f"Starting up at: {ADDRESS}") + self.server_socket = create_server(ADDRESS) + # set socket to non-blocking mode + self.server_socket.setblocking(False) + except OSError: + self.server_socket.close() + print("\nServer stopped.") + + def accept(self) -> None: + try: + conn, address = self.server_socket.accept() + print(f"Connected to {address}") + # making this connection non-blocking + conn.setblocking(False) + self.clients.add(conn) + except BlockingIOError: + # [Errno 35] Resource temporarily unavailable + # indicates that "accept" returned without results + pass + + def serve(self, conn: socket) -> None: + """Serve the incoming connection by sending and receiving data.""" + try: + while True: + data = conn.recv(BUFFER_SIZE) + if not data: + break + try: + order = int(data.decode()) + response = f"Thank you for ordering {order} pizzas!\n" + except ValueError: + response = "Wrong number of pizzas, please try again\n" + print(f"Sending message to {conn.getpeername()}") + # send a response + conn.send(response.encode()) + except BlockingIOError: + # recv/send returns without data + pass + + def start(self) -> None: + """Start the server by continuously accepting and serving incoming + connections.""" + print("Server listening for incoming connections") + try: + while True: + self.accept() + for conn in self.clients.copy(): + self.serve(conn) + finally: + self.server_socket.close() + print("\nServer stopped.") + + +if __name__ == "__main__": + server = Server() + server.start() +``` + +### Sample Output +#### Server +``` +Starting up at: ('127.0.0.1', 12345) +Server listening for incoming connections +Connected to ('127.0.0.1', 57283) +Sending message to ('127.0.0.1', 57283) +Sending message to ('127.0.0.1', 57283) +Sending message to ('127.0.0.1', 57283) +``` +### Terminal +``` +nc 127.0.0.1 12345 +a +Wrong number of pizzas, please try again +123 +Thank you for ordering 123 pizzas! +11 +Thank you for ordering 11 pizzas! +```