Java provides all the capabilities required to develop socket-based applications relatively easilyand it hides all the complexity involved.
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 Classes
Java 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 classesand how to use themin 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.
Figure 1 shows a screenshot of the server console when it starts.
Figure 1. The Server Console When It Starts:
Here is a screenshot of the server console when it starts.
Writing the Client Using SocketsCode Listing 2
provides a Java example for writing a client component using sockets.
In this code, the client inputs the server name and the port through which it deliver arguments for creating a socket connection. When the socket is created successfully, it can then talk to the server with the input/output streams. The exception handling has to be effective to pinpoint any problems in the connection.
Figure 2 shows a screenshot of the server console when the client starts, Figure 3 shows a screenshot of the client console, Figure 4 shows a screenshot of the server console when the client starts communicating, and Figure 5 shows a screenshot of the client console during communication.
Figure 2. Server Console When the Client Starts:
Here is a screenshot of the server console when the client starts.
Figure 3. The Client Console:
Here is a screenshot of the client console.
Figure 4. The Server Console When the Client Starts Communicating:
Here is a screenshot of the server console when the client starts communicating.
Figure 5. The Client Console During Communication:
Here is a screenshot of the client console during communication.
As you start using the application, you can think of numerous enhancements to this example.
Care and Feeding of Your Applications
It is important to close all open resources, such as file handlers, socket connections, and any other open entities because these will lead to memory-leak issues in the long run.
For Further Reading
"All About Sockets" (from java.sun.com)
About the AuthorSridhar M S is a Java developer from Bangalore, India. He holds a Master's degree in Computer Science.