Led by Prof. Yossi Oren.
Team Members:
- Aaron Iziyaev
- Adam Rammal
Our approach is inspired by the reactor design pattern, with minimal modifications to suit the needs of this project. We used Python's Executor to efficiently manage threads, ensuring quick responses to multiple requests. This implementation leverages both TCP and UDP channels to maximize efficiency and performance.
- Thread Management: The server operator can configure the number of worker threads, which determines the number of concurrent requests the server can handle.
- Thread-Safe Sockets: We took advantage of Python’s socket library, which is thread-safe, eliminating the need for complex queue-based solutions for I/O operations.
- UDP & TCP Channels: The server uses both UDP and TCP channels to handle incoming client requests. UDP handles broadcasting offers, while TCP manages actual data transfers.
- Broadcasting: UDP broadcasting is used to send server offers to clients in the local network, enabling automatic client discovery.
- To start the server, run
SpeedTestServer.py. You'll be prompted for several configuration inputs:- Server IP: This IP is used to calculate the broadcast address.
- UDP Port: The UDP port that the server will use for broadcasting.
- TCP Port: The TCP port for communication between the server and clients.
- Subnet Mask: Required for the server to calculate the broadcast address.
- Broadcast Port: The port clients listen to for server offers.
- Worker Threads: This determines the number of worker threads to handle client requests, ensuring high concurrency.
- Start Server Confirmation: The server will wait for a confirmation (
y) before starting
Note that steps (i,iv) we're left in since it made the code much more straight forward and it had been left in since we developed the server under the (reasonable and fair) assumption that an IT professional will operate the server.
Once configured, the server will begin broadcasting offers on the specified UDP port and listen for client requests on the TCP port.
- Connection Setup:
- Specify the number of TCP and UDP connections the client will use for speed tests.
- Port Configuration:
- Enter the initial port, which will be incremented for each connection to create unique ports for each client request. This port should match the server's broadcast port.
- File Size:
- Enter the file size the client will request from the server for the speed test.
The client will automatically listen for UDP offers, and upon receiving an offer, it will establish TCP and UDP connections to the server and begin the speed test.
The server utilizes two main channels: TCP and UDP.
-
TCP Channel: The TCP server is responsible for handling client connections and transferring files. It listens on a specified port, accepts client connections, and sends the requested file to the client.
Key aspects:
- Uses a pool of worker threads (
ThreadPoolExecutor) to handle multiple client connections concurrently. - Upon receiving a request, the server sends a file of the requested size over TCP to the client.
- Uses a pool of worker threads (
-
UDP Channel: The UDP server listens for broadcast offers and manages data transfers over the UDP protocol.
Key aspects:
- Sends broadcast offers to clients, enabling them to discover the server and connect.
- Once a client sends a request, the UDP server responds with the requested file in chunks.
- Supports multiple concurrent clients by spawning threads to handle each client request.
- UDP Broadcast: The server broadcasts offers to all devices in the subnet. Clients listen for these offers and then connect to the server.
- TCP Data Transfer: After receiving the offer, clients establish a TCP connection to the server, request a file, and the server responds with the requested data over the TCP connection.
- Thread Pool Executor: A thread pool is used to efficiently manage multiple concurrent connections. Each connection, whether TCP or UDP, is handled in a separate thread.
This solution successfully implements a high-performance server capable of handling concurrent TCP and UDP connections for speed testing. The use of thread management and broadcasting ensures efficiency and scalability. We're proud of the result and look forward to finishing the next assignment. 😄
- TCP Handling: The server uses a dedicated thread for each client connection. Upon receiving the file size from the client, the server sends back a file of that size.
- UDP Handling: The server broadcasts UDP offers and responds to requests with file data in chunks.
- Broadcasting: The server utilizes Python's
socketlibrary for broadcast communication, calculating the broadcast IP address usingipaddress.IPv4Network.