Implement low-level client-server communication using TCP sockets.
Socket programming is the foundation of network communication in Java. A socket provides an endpoint for sending or receiving data across a computer network. The `java.net` package contains the necessary classes, primarily `Socket` and `ServerSocket`, for creating TCP-based client-server applications. TCP (Transmission Control Protocol) is a connection-oriented protocol that guarantees reliable, ordered delivery of data. The server side of the communication creates a `ServerSocket` object, specifying a port number to listen on. A port is a numerical identifier that distinguishes different services running on the same machine. The server then calls the `accept()` method on the `ServerSocket`. This is a blocking call, meaning the server's execution will pause and wait until a client tries to connect. The client side creates a `Socket` object, providing the IP address or hostname of the server and the port number it's listening on. This initiates a connection request to the server. Once the server receives the request, the `accept()` method returns a new `Socket` object that is connected to the client. Now, both the client and the server have a `Socket` object, and a two-way communication channel is established. Each socket has an `InputStream` and an `OutputStream`, which can be used to read data from and write data to the other end of the connection, respectively. This low-level control is powerful but requires careful management of the communication protocol and error handling.