In client/server applications, the client and server components usually do not reside on the same computer (i.e., the client could be installed on a computer that is different from the one hosting the server installation); yet logically they are components of the same application. To enable the client and server components to communicate with each other over a network, systems often rely heavily on sockets.
Because Java provides the required capabilities for developing socket-based applications relatively easily and hides all the complexity involved, Java developers have an advantage in providing quick solutions to networking problems.
The ServerSocket and Socket ClassesJava supports socket development through the java.net package. In particular, ServerSocket and Socket are the socket-related classes. They provide infrastructure for server and client development, respectively. This article explores these classes—and how to use them—in more detail.
You use the ServerSocket class on the server component, where it listens for incoming requests. ServerSocket generally is bound to a port, always active, and non-blocking. This means that it immediately transfers or hands over any incoming request to a different component and then continues listening for new incoming requests.
To connect with the server component, the client component simply requests a connection to the computer where it expects the server to be running. It includes the computer name and the port to which the server is bound in this request. The resulting connection is permanent for the client; it will not be shared with any other instance of the client software running on the same machine.
Confused? Here is the concept in a nutshell:
- The server listens on the port to which it is bound and waits for incoming requests.
- When it receives a connection request, it creates a socket and associates the new connection to that socket.
- From then on, the client will communicate with the server via this newly created socket (although it is not aware of it).
Imagine achieving this setup using native code. It would be a lot of work, and if you weren’t aware of the low-level constraints (like many developers), you would end up producing poor quality code. Luckily, the Java socket APIs are well tested and used by a large group of developers, which ensures that all possible hidden issues are caught and addressed. That is why developers using Java can produce high-quality client/server applications based on sockets.
Writing the Server Using SocketsCode Listing 1 provides a Java example for writing a server component using sockets. In this code, the server binds itself with a ServerSocket on to a pre-determined port. This port will be the one to which clients can request connections. The server then awaits client connection requests on the ServerSocket. When it receives them, it will create a new socket and hand the connection over to it.
The code uses the accept() method on the ServerSocket class, designating the socket as the one responsible for communication with the client. All information to and from the client will be sent and received via this socket. The getInputStream() and getOutputStream() methods are used for the communication with the client.