Java Socket Programming
Java Socket Programming
Socket programming is used for the communication between the applications, i.e., client and server running on different JRE may be connection-oriented or connectionless. The client program can be designed using the Socket class. The server program can be created using the ServerSocket class. Both Socket and ServerSocket classes are the inbuilt classes in the java.net package. A client program instantiates a Socket object on its end in the communication and attempts to connect the Socket to a server. When the connection is made, the server can communicate by writing to and reading from the Socket.
The following steps occur when establishing a connection between two computers using sockets:
- The server creates a ServerSocket object that denotes on which port number communication is going to occur.
- The server calls the accept() method of the ServerSocket class. The accept() method waits until a client connects to the server on the given port.
- A client creates a Socket object, indicating the server name and the port number to which it connects on the internet.
- The accept() method gives a reference to a Socket on the server that is connected to the client’s Socket.
- After the connection is established, communication can occur using I/O streams. Every Socket has both an OutputStream and InputStream. The OutputStream of the client is connected to the server’s InputStream, and the client’s InputStream is connected to the server’s OutputStream. In two-way communication, the data can be sent across both streams at the same time.
The Socket class
Socket class indicates the socket that both the client and the server used to communicate with each other. The client has a Socket object by instantiating its class, rather than the server gets the object of Socket by the return value of the accept() method. Socket class designs a client program.
The constructor of the Socket class:
Syntax:
Socket s=new Socket(“localhost”,8080); //localhost—port name and 8080—port number
Constructor | Description |
public Socket(String host1, int port1)throws UnknownHostException, IOException | This method attempts to connect to a specific server at a specific port. |
public Socket(InetAddress host1, int port1)throws IOException | It indicates to connect to the specified server at the specified port, except that the host denotes an InetAddress object. |
public Socket(String host, int port, InetAddress inet, int localPort)throws IOException | It connects to the specified host and port, creating a socket on the localhost at a specified address and port. |
public Socket(InetAddress host1, int port, InetAddress localAdd, int localPort)throws IOException | It is identical to the previous constructor, and the host denotes the InetAddress object instead of a String. |
public Socket() | This method is used to create an unconnected socket. The connect() method is used to connect this socket to a server. |
Method of Socket class
Method | Description |
public void connect(SocketAddress host1, int timeout1)throws IOException | This method connects the socket to the particular host. This method is used when you instantiate the socket using the no-argument constructor. |
public InetAddress getInetAddress(void) | It returns the address of the other computer when the socket is connected to the internet. |
public int getLocalPort() | It returns the port to which the socket is bound to, on the local machine. |
public SocketAddress getRemoteSocketAddress() | It returns the address of the remote socket. |
public InputStream getInputStream()throws IOException | It returns the input stream of the socket. The input stream connects to the output stream of the remote socket. |
public OutputStream getOutputStream()throws IOException | It returns the output stream of the socket. The output stream connects to the input stream of the remote socket. |
public void close() throws IOException | It closes the socket, which makes this Socket object no longer capable of connecting again to any server. |
public OutputStream getOuputStream() :
The above method writes on the data from the client program to the server program and from the server program to the client program, which returns the OutputStream class object. A syntax is given below that tells how we can use it in the Socket class:
Syntax:
Socket s=new Socket(“localhost”,8080); OutputStream os=new s.getOutputStream(); DataOutputStream dis=new DataOutputStream(os);
public InputStream getInputStream()
It is used by the server to read the data from the client system or by the client from the server system that returns an InputStream class object.
A syntax is given below that tells how we can use it in the Socket class:
Syntax:
Socket s=new Socket(“localhost”,10); InputStream input=new s.getInputStream(); DataInputStream datainput=new DataInputStream(is);
public synchronized void close()
To close an object of Socket class or it is used to close client requests. A syntax is given below that tells how we can incorporate it in the Socket class:
Syntax:
Socket s=new Socket(“localhost”,8080); s.close();
The ServerSocket class
This class can be used to create a ServerSocket instance that is used by server applications to listen to client’s requests. If the application has successfully bound to the specified port, the ServerSocket constructor does not throw an exception and is ready for client requests.
The ServerSocket class has four constructors:
Constructor | Description |
public ServerSocket(int port)throws IOException | It attempts to create a ServerSocket that binds to the given port. |
public ServerSocket(int port, int backlogs)throws IOException | It also attempts to create a ServerSocket bound to the specified port, and the backlogs parameter specifies how many incoming clients have to be stored in await queue. |
public ServerSocket(int port, int backlog, InetAddress add)throws IOException | It also attempts to create a ServerSocket instance as above, and the InetAddress parameter that specifies the local IP address. The InetAddress is used for the servers that have multiple IP addresses, allowing the server to specify which of its IP addresses are accepting client requests on the internet. |
public ServerSocket() throws IOException | It creates an unbound server socket. It uses the bind() method when you are ready to bind the server socket. |
Methods of the ServerSocket class
Method | Description |
public int getLocalPort() | It returns the port of the server socket, which is listening on the network. |
public Socket accept()throws IOException | It waits for an incoming client. |
public void setSoTimeout(int timeout) | It sets the time-out value for how long the server socket waits for a client during the accept() method. |
public void bind(SocketAddress host, int backlog) | This method binds the Socket to the specified server and port in the SocketAddress object. |
When the ServerSocket calls accept(), the method does not return until a client connects. After a client connects, the ServerSocket creates a new Socket on an unspecified port and returns a reference to this new socket. A connection now exists between the client and the server, and communication can begin. ServerSocket object is used to communicate with clients. ServerSocket class is used to design a server program. It has some constructors and methods that are used in designing the server program. ServerSocket class contains a constructor that is used to create a separate port number to run the server program.
Syntax:
ServerSocket ss=new ServerSocket(8080);
public Socket accept()
It is used to accept the client's request on the internet. The following syntax is given below, which tells how we can use it in the ServerSocket class.
Syntax:
Socket s=new Socket(“localhost”,8080); ServerSocket ss=new ServerSocket(8080); Socket s=ss.accept();
The following are some examples of TCP protocol:
Example 1: One-way communication from the client to the server.
Client-side programming:
import java.net.*; import java.io.*; class Client { public static void main(String s1[]) { try { Socket s=new Socket("localhost",20); //creates the socket instance System.out.println(s); //DataOutputStream class is to create an output stream to send response to the server. DataOutputStream d1=new DataOutputStream(s.getOutputStream()); d1.writeUTF("hello server"); d1.close(); } catch(Exception e) { System.out.println(e); } } }
Server side programming
import java.net.*; import java.io.*; class Server { public static void main(String s1[]) { try { ServerSocket ss=new ServerSocket(20); System.out.println("server is started......"); Socket s=ss.accept(); //establishing connection and waits for the client. System.out.println(s); //DataInputStream class is to create an input stream to receive a response from the client. DataInputStream ds=new DataInputStream(s.getInputStream()); String msg=(String)ds.readUTF(); System.out.println(msg); } catch(Exception e) { e.printStackTrace(); } } }
The output of the client:

The output of the server:

Example 2: Peer to peer chatting, i.e., (Read-Write from both side) Two-way communication:
The client first writes to the server, then the server receives and prints the text. Then the server writes to the client, and the client receives and prints the text.
Client side programming:
import java.net.*; import java.io.*; class MyClient1{ public static void main(String s1[])throws Exception{ Socket s=new Socket("localhost",10); //DataInputStream class is to create an input stream to receive response from the server. DataInputStream din=new DataInputStream(s.getInputStream()); //DataOutputStream class is to create output stream to send information to the server socket. DataOutputStream dout=new DataOutputStream(s.getOutputStream()); BufferedReader br3=new BufferedReader(new InputStreamReader(System.in)); String str="",str2=""; while(!str.equals("stop")){ str=br3.readLine(); dout.writeUTF(str); dout.flush(); str2=din.readUTF(); System.out.println("Server says: "+str2); } dout.close(); s.close(); }}
Server side programming:
import java.net.*; import java.io.*; class MyServer1{ public static void main(String s2[])throws Exception{ ServerSocket ss=new ServerSocket(10); Socket s=ss.accept(); // DataInputStream creates an input stream to receive input from the client. DataInputStream din=new DataInputStream(s.getInputStream()); //DataOutputStream creates an output stream to send information to the client. DataOutputStream dout=new DataOutputStream(s.getOutputStream()); BufferedReader br=new BufferedReader (new InputStreamReader(System.in)); String str="",str2=""; while(!str.equals("stop")){ str=din.readUTF(); System.out.println("client says: "+str); str2=br.readLine(); dout.writeUTF(str2); dout.flush(); } din.close(); s.close(); ss.close(); }}
The output of the client:

The output of the server:

Example 3: Echo Server for communication: Whatever message the client writes, it reflects towards the client as it is, from the server
The client side:
import java.io.*; import java.net.*; public class MyClient2 { Socket s; DataInputStream din; DataOutputStream dout; public MyClient2() { try { s=new Socket("localhost",10); System.out.println(s); din=new DataInputStream(s.getInputStream()); dout=new DataOutputStream(s.getOutputStream()); clientChat(); } catch(Exception e) { System.out.println(e); } } public void clientChat() throws IOException { BufferedReader br3=new BufferedReader(new InputStreamReader(System.in)); String s1; do { s1=br3.readLine(); dout.writeUTF(s1); dout.flush(); System.out.println("server message:"+din.readUTF()); } while(!s1.equals("stop")); } public static void main(String s[]) { new MyClient2(); } }
The server side:
import java.io.*; import java.net.*; public class MyServer2 { ServerSocket ss; Socket s; DataInputStream dis; DataOutputStream dos; public MyServer2() { try { System.out.println("server started"); ss=new ServerSocket(10); s=ss.accept(); System.out.println("client connected"); dis=new DataInputStream(s.getInputStream()); dos=new DataOutputStream(s.getOutputStream()); serverChat(); } catch(Exception e) { System.out.println(e); } } public static void main(String s[]) { new MyServer2(); } public void serverChat() throws IOException{ String str; do { str=dis.readUTF(); System.out.println("client message"+str); dos.writeUTF(str); dos.flush(); } while(!str.equals("stop")); } }
The output of the client:

The output of the server:

Limitations of Socket programming
- You can share the resources locally but not globally.
- You cannot develop internet-based applications.
- You can develop only half-duplex applications.
- You cannot get services from universal protocols like http, ftp, etc.
- You cannot get services from universal server software like Tomcat, WebLogic, etc.
Note: Servlet and JSP technology has overcome these limitations.