Class TCPServer
- All Implemented Interfaces:
Runnable
This server implementation extends Thread to run asynchronously and provides the foundation
for the HTTP server. It handles the TCP/IP layer of communication, accepting incoming socket
connections and delegating HTTP request processing to an HTTPHandler.
Key features:
- Non-blocking server operation on a dedicated thread
- Thread pool-based request handling for efficient concurrency
- Graceful shutdown with proper resource cleanup
- Integration with
ServerLoggerfor operational logging - Support for virtual threads via configurable
ExecutorService
Architecture:
- Server socket binds to the specified TCP port
- Main server thread continuously accepts incoming connections
- Each accepted connection is submitted to the thread pool
- HTTPHandler processes the request in a worker thread
- Socket cleanup is handled automatically after request processing
Lifecycle:
// Create server instance ExecutorService pool = Executors.newVirtualThreadPerTaskExecutor(); TCPServer server = new TCPServer(8080, httpHandler, pool); // Start server (non-blocking) server.start(); // Server is now accepting connections... // Graceful shutdown server.stopServer();
Thread-safety: This class is designed to be instantiated once and started on a single thread.
The accept loop runs on the server's thread while request handling is distributed across
the thread pool. The stopServer() method can be called from any thread to initiate
graceful shutdown.
Error handling: The server catches and handles SocketException during shutdown,
and logs other exceptions that occur during operation. The server will continue running
even if individual request handling fails.
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from class Thread
Thread.Builder, Thread.State, Thread.UncaughtExceptionHandler -
Field Summary
Fields inherited from class Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY -
Constructor Summary
ConstructorsConstructorDescriptionTCPServer(int port, HTTPHandler handlerObject, ExecutorService pool) Constructs a TCPServer instance with the specified port, handler, and thread pool. -
Method Summary
Modifier and TypeMethodDescriptionvoidrun()Starts the server and continuously listens for incoming client connections.voidInitiates graceful shutdown of the server.Methods inherited from class Thread
activeCount, checkAccess, clone, currentThread, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, isVirtual, join, join, join, join, ofPlatform, ofVirtual, onSpinWait, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, sleep, start, startVirtualThread, stop, threadId, toString, yield
-
Constructor Details
-
TCPServer
Constructs a TCPServer instance with the specified port, handler, and thread pool.This constructor initializes the server socket and binds it to the specified port. The server is not started automatically;
Thread.start()must be called to begin accepting connections.Port binding considerations:
- Ports below 1024 typically require root/administrator privileges
- The port must not be in use by another process
- Port 0 can be used to automatically select an available port
- Common HTTP ports: 80 (HTTP), 443 (HTTPS), 8080 (alternative HTTP)
The thread pool should be configured based on expected load and concurrency model:
- Virtual threads:
Executors.newVirtualThreadPerTaskExecutor()- Recommended for high concurrency - Fixed thread pool:
Executors.newFixedThreadPool(n)- For controlled resource usage - Cached thread pool:
Executors.newCachedThreadPool()- For varying load
- Parameters:
port- The TCP port number on which the server will listen for connections. Must be in the range 0-65535. Port 0 allows automatic port selection.handlerObject- The HTTPHandler instance to process client requests. Must not be null.pool- The ExecutorService for handling requests concurrently. Must not be null and should be in a running state.- Throws:
IOException- If the server socket cannot be created or bound to the specified port. Common causes: port already in use, insufficient permissions, invalid port number.Exception- If any other error occurs during server initialization.
-
-
Method Details
-
run
public void run()Starts the server and continuously listens for incoming client connections.This method implements the main server loop that:
- Logs server startup with the bound port number
- Enters an infinite accept loop waiting for client connections
- Accepts each connection and submits it to the thread pool for processing
- Continues accepting new connections even if individual requests fail
- Exits gracefully when
stopServer()is called
The accept loop is blocking - when no connections are pending, the thread waits until a client connects. This is efficient as it doesn't consume CPU while waiting.
Error handling:
SocketException- Expected during shutdown when socket is closed, silently ignored as it's part of normal shutdown procedure- Other exceptions - Logged to standard error but server continues attempting to accept connections
This method runs on the server's thread (not the calling thread) since TCPServer extends Thread. Call
server.start()to begin execution, notserver.run().Note: This method contains German comments in the exception handlers from the original implementation explaining exception handling behavior.
-
stopServer
public void stopServer()Initiates graceful shutdown of the server.This method performs an orderly shutdown sequence:
- Closes the server socket, which causes the accept loop to exit with a
SocketException - Shuts down the thread pool, preventing new tasks from being submitted
- Prints a shutdown confirmation message to standard output
Shutdown behavior:
- New connections are immediately rejected once the socket is closed
- The server thread (running
run()) will exit after socket closure - The thread pool begins orderly shutdown (completes submitted tasks but accepts no new ones)
- In-progress requests are allowed to complete before the pool terminates
This method can be safely called from any thread and can be invoked multiple times (subsequent calls have no effect as the socket is already closed).
Thread pool shutdown: The method calls
ExecutorService.shutdown()rather thanshutdownNow(), allowing graceful completion of in-flight requests. If immediate termination is required, additional logic should be added to interrupt worker threads.IOException handling: Any IOException thrown during socket closure is silently ignored since shutdown is already in progress and the exception doesn't affect the outcome.
- Closes the server socket, which causes the accept loop to exit with a
-