Recently in one of my freelance projects, I was asked to replace existing Java Sockets with the websockets. In this series of tutorials, I will explain some basic details of Java Sockets and Websockets. I will also provide a working code in which 2 servers communicate via WebSockets.
During the migration from Java Sockets to WebSockets I faced a couple of issues, I will also explain how I resolved those issues.
Let us start with some basics of Java Sockets and Socket Programming in Java.
What is a socket in Java?
- In Java, a socket is a programming mechanism that enables communication between two computers over a network.
- We can say a socket is one endpoint of a two-way communication link between two programs running on the network.
- A socket connection means the two machines have information about each other’s network location (IP Address) and TCP port, which allows us to send and receive data.
There are two types of sockets in Java, both are present in the java.net package:
1). ServerSocket: This class implements a server socket, which waits for incoming client connections. Once a connection is established, it returns a new Socket object that represents the connection to the client.
There are two important methods of the java.net.ServerSocket class:
a). public Socket accept(): This method returns the socket and establishes a connection between server and client.
b). public synchronized void close(): It closes the server socket.
2). Socket: This class represents a client-side socket, which can connect to a server socket. It can also be used for communication with the server once the connection is established.
By using the java.net.Socket class instead of relying on native code, your Java programs can communicate over the network in a platform-independent fashion.
Important methods of java.net.Socket class:
a). public InputStream getInputStream(): returns the InputStream attached with this socket.
b). public OutputStream getOutputStream(): returns the OutputStream attached with this socket.
c). public synchronized void close(): closes this socket
Here is the sample program of a basic server and client using sockets in Java:
What is the difference between a server socket and a client socket?
A Server Socket listens for incoming connection requests from clients. Once a connection is accepted, the server socket creates a new socket dedicated to that particular client for further communication. Whereas A Client Socket initiates a connection to a server socket. Once the connection is established, the client socket can send and receive data to and from the server.
We can say that server sockets are used by server programs to listen for incoming connections, while client sockets are used by client programs to initiate connections to servers. The two types of sockets work together to enable communication between processes over a network.
In essence, while both are endpoints in a two-way communication link, the server socket accepts connections, and the client socket initiates them.
How would you handle socket exceptions in your code?
Exception handling is crucial in socket programming. Common exceptions include IOException and SocketException. We can use try-catch blocks to handle these exceptions and implement appropriate error-handling logic. In the catch block, we can just log the error message, terminate the program or if possible attempt recovery after some delay. We need to ensure resources are freed even when exceptions occur, for this, we can close sockets in a finally block. This prevents resource leaks which could lead to system instability.
Explain bind(), and accept() functions in socket programming.
In socket programming, particularly in the context of TCP/IP communication, the bind(), listen(), and accept() functions are commonly used to set up and manage server sockets.
a). accept(): This function accepts an incoming connection from the queue, creating a new socket specifically for that connection. This is similar to taking a letter out of your mailbox. If no pending requests are in the queue, accept() blocks until a connection request arrives.
b). bind(): It associates a socket with a specific network address (IP address and port number) on the local machine so it can receive data from that specific endpoint. If the specified address is null, the system will automatically pick up an ephemeral port and a valid local address to bind this socket.
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new java.net.InetSocketAddress("localhost", portNumber));
There are 2 overloaded versions of bind methods are available:
1). public void bind(SocketAddress endpoint) throws IOException
2). public void bind(SocketAddress endpoint, int backlog) throws IOException
Where the endpoint represents the IP address and port number to bind to. The backlog is the requested maximum number of pending connections on the socket. The value of the backlog should always be greater than 0, if it's zero or negative, then an implementation-specific default value will be used.
The bind() can throw an IOException if the bind operation fails, or if the socket is already bound. If the SecurityManager is present and its checkListenmethod doesn't permit the operation then SecurityException will be thrown. It will throw an IllegalArgumentException if the endpoint is a SocketAddress subclass not supported by this socket.
Explain the concept of blocking and non-blocking sockets.
- In simple words, blocking sockets wait for an operation to complete before allowing the program to proceed, while non-blocking sockets allow the program to continue executing even if an operation is not completed.
- If a process tries to read from a blocking socket and there is no data available, it will wait until data is received. Similarly, if it tries to write to a blocking socket and the buffer is full, it will wait until there is space available.
- In contrast, if a process tries to read from a non-blocking socket and there is no data available, it doesn't wait and returns an error or a special value. Similarly, if it tries to write to a non-blocking socket and the buffer is full, it doesn't wait and returns an error or a special value.
- In Java, you can set a socket to be non-blocking using the SocketChannel class.
If you enjoy our content and want to support us, please consider donating via gpay, phonepay or paytm on +91 9920600280. Also, I’d appreciate if you’d buy me a coffee☕
Keep learning and growing!
-K Himaanshu Shuklaa..
Sooo thank you amazing 😍
ReplyDelete