Socket programming in Java
This is a quick guide/tutorial to learning socket programming in Java.
The Socket class is documented at http://docs.oracle.com/javase/1.4.2/docs/api/java/net/Socket.html
To summarise the basics, sockets are the fundamental "things" behind any kind of network communications done by your computer.
For example when you type www.google.com in your web browser, it opens a socket and connects to google.com to fetch the page and show it to you. Same with any chat client like gtalk or skype.
In general any network communication goes through a socket.
Before you begin
This tutorial assumes that you already have a basic knowledge of java and can compile and run java programs.
So lets begin with sockets.
1. Creating a socket
This first thing to do is create a socket.
Quick Example :
Socket s = new Socket();
The above creates a socket object that can be used for other operations like connecting and sending data.
The socket class is actually a TCP socket, although its not specified (like its done in C or python for example).
Also, it is a "client socket" since it can be used only to make socket clients and not servers. More on this later in this article.
UDP sockets in java are created using the class DatagramSocket, and we shall look into this in another article.
Ok , so you have created a socket successfully. But what next ? Next we shall try to connect to some server using this socket. We can connect to www.google.com
2. Connect to a Server
We connect to a remote server on a certain port number. So we need 2 things , IP address and port number to connect to. So you need to know the IP address of the remote server you are connecting to. Here we used the ip address of google.com as a sample.
Now that we have the ip address of the remote host/system, we can connect to ip on a certain 'port' using the connect function.
Quick example
//java socket client example import java.io.*; import java.net.*; public class socket_client { public static void main(String[] args) throws IOException { Socket s = new Socket(); String host = "www.google.com"; try { s.connect(new InetSocketAddress(host , 80)); } //Host not found catch (UnknownHostException e) { System.err.println("Don't know about host : " + host); System.exit(1); } System.out.println("Connected"); } }
Run the program
$ javac socket_client.java && java socket_client Connected
It creates a socket and then connects. Try connecting to a port different from port 80 and you should not be able to connect which indicates that the port is not open for connection. This logic can be used to build a port scanner.
Tip
The Socket object can be connected at the time of creation.
Socket s = new Socket(host , port);
OK, so we are now connected. Lets do the next thing , sending some data to the remote server.
3. Sending Data
//java socket client example import java.io.*; import java.net.*; public class socket_client { public static void main(String[] args) throws IOException { Socket s = new Socket(); String host = "www.google.com"; PrintWriter s_out = null; try { s.connect(new InetSocketAddress(host , 80)); System.out.println("Connected"); //writer for socket s_out = new PrintWriter( s.getOutputStream(), true); } //Host not found catch (UnknownHostException e) { System.err.println("Don't know about host : " + host); System.exit(1); } //Send message to server String message = "GET / HTTP/1.1\r\n\r\n"; s_out.println( message ); System.out.println("Message send"); } }
In the above example , we first connect to www.google.com and then send the string message "GET / HTTP/1.1\r\n\r\n" to it. The message is actually an "http command" to fetch the mainpage of a website.
Now that we have send some data , its time to receive a reply from the server. So lets do it.
4. Receiving Data
//java socket client example import java.io.*; import java.net.*; public class socket_client { public static void main(String[] args) throws IOException { Socket s = new Socket(); String host = "www.google.com"; PrintWriter s_out = null; BufferedReader s_in = null; try { s.connect(new InetSocketAddress(host , 80)); System.out.println("Connected"); //writer for socket s_out = new PrintWriter( s.getOutputStream(), true); //reader for socket s_in = new BufferedReader(new InputStreamReader(s.getInputStream())); } //Host not found catch (UnknownHostException e) { System.err.println("Don't know about host : " + host); System.exit(1); } //Send message to server String message = "GET / HTTP/1.1\r\n\r\n"; s_out.println( message ); System.out.println("Message send"); //Get response from server String response; while ((response = s_in.readLine()) != null) { System.out.println( response ); } } }
Here is the output of the above code :
$ javac socket_client.java && java socket_client Connected Message send HTTP/1.1 302 Found Location: http://www.google.co.in/ Cache-Control: private Content-Type: text/html; charset=UTF-8 Set-Cookie: domain=; expires=Mon, 01-Jan-1990 00:00:00 GMT; path=/; domain=.google.com Set-Cookie: PREF=ID=8cab6cb84196272d:FF=0:TM=1343284818:LM=1343284818:S=v6CKP6OQ7-MwR9Ho; expires=Sat, 26-Jul-2014 06:40:18 GMT; path=/; domain=.google.com Set-Cookie: NID=62=g7qvBSlfd6RLHqowhnvlKcu1hr3EtfMzv39ggUYhjtC0ow7-2gTW5mVnePH5HyRS5D2oB4UAmbGCZTVs0MF6EQojZRTuhSd-6-9qaJeyfegjHvNwarfE8yB5Kz_I8GS0; expires=Fri, 25-Jan-2013 06:40:18 GMT; path=/; domain=.google.com; HttpOnly P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info." Date: Thu, 26 Jul 2012 06:40:18 GMT Server: gws Content-Length: 221 X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"> <TITLE>302 Moved</TITLE></HEAD><BODY> <H1>302 Moved</H1> The document has moved <A HREF="http://www.google.co.in/">here</A>. </BODY></HTML>
google.com replied with the content of the page we requested. Quite simple!
Now that we have received our reply, its time to close the socket.
5. Close socket
Function close
is used to close the socket.
//close the i/o streams s_out.close(); in.close(); //close the socket s.close();
Thats it.
Lets Revise
So in the above example we learned how to :
1. Create a socket
2. Connect to remote server
3. Send some data
4. Receive a reply
Its useful to know that your web browser also does the same thing when you open www.google.com
This kind of socket activity represents a CLIENT. A client is a system that connects to a remote system to fetch data.
The other kind of socket activity is called a SERVER. A server is a system that uses sockets to receive incoming connections and provide them with data. It is just the opposite of Client. So www.google.com is a server and your web browser is a client. Or more technically www.google.com is a HTTP Server and your web browser is an HTTP client.
Now its time to do some server tasks using sockets.
Server Programming
OK now onto server things. Servers basically do the following :
1. Open a socket
2. Bind to a address(and port).
3. Listen for incoming connections.
4. Accept connections
5. Read/Send
We have already learnt how to open a socket. So the next thing would be to bind it.
1. Bind socket to a port
To create a socket and bind it to a particular port number, all that needs to be done is to create an object of class ServerSocket. The constructor takes 2 parameters, first is the local port number and the 2nd is the backlog number.
Quick example
ServerSocket s = new ServerSocket(5000 , 10);
The above piece of code will create a socket and bind it to local machine port number 5000. Its important to note that the socket is already listening for connections. So the next thing is to accept connections by calling the accept method on the socket.
2. Accept connection
Function accept
is used for this.
//java server example import java.io.*; import java.net.*; public class socket_server { public static void main(String args[]) { ServerSocket s = null; Socket conn = null; PrintStream out = null; BufferedReader in = null; String message = null; try { //1. creating a server socket - 1st parameter is port number and 2nd is the backlog s = new ServerSocket(5000 , 10); //2. Wait for an incoming connection echo("Server socket created.Waiting for connection..."); //get the connection socket conn = s.accept(); //print the hostname and port number of the connection echo("Connection received from " + conn.getInetAddress().getHostName() + " : " + conn.getPort()); //3. get Input and Output streams out = new PrintStream(conn.getOutputStream()); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream())); out.println("Welcome. Server version 1.0"); out.flush(); } catch(IOException e) { System.err.println("IOException"); } //5. close the connections and stream try { in.close(); out.close(); s.close(); } catch(IOException ioException) { System.err.println("Unable to close. IOexception"); } } public static void echo(String msg) { System.out.println(msg); } }
Output
Run the program. It should show
$ javac socket_server.java && java socket_server Server socket created.Waiting for connection...
So now this program is waiting for incoming connections on port 5000. Dont close this program , keep it running.
Now a client can connect to it on this port. We shall use the telnet client for testing this. Open a terminal and type
$ telnet localhost 5000
It will immediately show
$ telnet localhost 5000 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Welcome. Server version 1.0 Connection closed by foreign host.
And the server output will show
$ javac socket_server.java && java socket_server Server socket created.Waiting for connection... Connection received from localhost : 34513
So we can see that the client connected to the server. Try the above steps till you get it working perfect.
We accepted an incoming connection but closed it immediately. This was not very productive. There are lots of things that can be done after an incoming connection is established. Afterall the connection was established for the purpose of communication.
3. Simple ECHO server
Now lets modify the above program such that it takes some input from client and replies back with the same message.
//java server example import java.io.*; import java.net.*; public class socket_server { public static void main(String args[]) { ServerSocket s = null; Socket conn = null; PrintStream out = null; BufferedReader in = null; String message = null; try { //1. creating a server socket - 1st parameter is port number and 2nd is the backlog s = new ServerSocket(5000 , 10); //2. Wait for an incoming connection echo("Server socket created.Waiting for connection..."); //get the connection socket conn = s.accept(); //print the hostname and port number of the connection echo("Connection received from " + conn.getInetAddress().getHostName() + " : " + conn.getPort()); //3. get Input and Output streams out = new PrintStream(conn.getOutputStream()); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream())); out.println("Welcome. Server version 1.0"); out.flush(); //4. The two parts communicate via the input and output streams do { //read input from client message = (String)in.readLine(); echo("client>" + message); if(message != null) { out.println(message); } else { echo("Client has disconnected"); break; } } while(!message.equals("bye")); } catch(IOException e) { System.err.println("IOException"); } //5. close the connections and stream try { in.close(); out.close(); s.close(); } catch(IOException ioException) { System.err.println("Unable to close. IOexception"); } } public static void echo(String msg) { System.out.println(msg); } }
Run the above code in 1 terminal. And connect to this server using telnet from another terminal and you should see this :
$ telnet localhost 5000 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Welcome. Server version 1.0 hi hi how are you how are you
So the client(telnet) received a reply from server.
In the above example we can see that the server is handling the client very well. But there is a problem. It can only handle one client at a time. If other clients connect to it, they would get connected but nothing more would happen.
4. Handling Multiple Connections
To handle every connection we need a separate handling code to run alongside the main server that is accepting new connections. One way to achieve this is using threads. The main server program accepts a connection and creates a new thread to handle communication for the connection, and then the server goes back to accept more connections.
We shall now use threads to create handlers for each connection the server accepts.
//java server example import java.io.*; import java.net.*; public class socket_server { public static void main(String args[]) { ServerSocket s = null; Socket conn = null; try { //1. creating a server socket - 1st parameter is port number and 2nd is the backlog s = new ServerSocket(5000 , 10); //2. Wait for an incoming connection echo("Server socket created.Waiting for connection..."); while(true) { //get the connection socket conn = s.accept(); //print the hostname and port number of the connection echo("Connection received from " + conn.getInetAddress().getHostName() + " : " + conn.getPort()); //create new thread to handle client new client_handler(conn).start(); } } catch(IOException e) { System.err.println("IOException"); } //5. close the connections and stream try { s.close(); } catch(IOException ioException) { System.err.println("Unable to close. IOexception"); } } public static void echo(String msg) { System.out.println(msg); } } class client_handler extends Thread { private Socket conn; client_handler(Socket conn) { this.conn = conn; } public void run() { String line , input = ""; try { //get socket writing and reading streams DataInputStream in = new DataInputStream(conn.getInputStream()); PrintStream out = new PrintStream(conn.getOutputStream()); //Send welcome message to client out.println("Welcome to the Server"); //Now start reading input from client while((line = in.readLine()) != null && !line.equals(".")) { //reply with the same message, adding some text out.println("I got : " + line); } //client disconnected, so close socket conn.close(); } catch (IOException e) { System.out.println("IOException on socket : " + e); e.printStackTrace(); } } }
Run the above server and open 3 terminals like before. Now the server will create a thread for each client connecting to it.
The telnet terminals would show :
$ telnet localhost 5000 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Welcome to the Server hi I got : hi how are you I got : how are you i am fine I got : i am fine
The server terminal might look like this
$ javac socket_server.java && java socket_server Server socket created.Waiting for connection... Connection received from localhost : 34907 Connection received from localhost : 35097
The above connection handler takes some input from the client and replies back with the same.
So now we have a server thats communicative. Thats useful now.
Conclusion
By now you must have learned the basics of socket programming in Java. You can try out some experiments like writing a chat client or something similar.
If you think that the tutorial needs some addons or improvements or any of the code snippets above dont work then feel free to make a comment below so that it gets fixed.
Thanks for sharing this information It is helpful information
} catch (UnknownHostException e) {
System.err.println(“Don’t know about host : “);
System.exit(1);
} catch (IOException e) {
System.out.println(“IO Exception ” + e.getMessage());
e.printStackTrace();
System.exit(1);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(“Array Exception ” + e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
}
The else case is where the socket listen to the request going from local system to the remote system and the if case is where the socket listen to the incoming response.
An attachment is one endpoint of a two-way correspondence interface between two programs running on the system. The attachment is bound to a port number with the goal that the TCP layer can distinguish the application that information is bound to be sent.
I like that you built up the client file talking to an existing server (google) instead of relying on the user to create a working server and client simultaneously. Thanks for sharing
A socket is one endpoint of a two-way communication link between two programs running on the network. The socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sent.
thanks for sharing informative content about java socket programming. i think it’s best way for beginners to learn java language.
Great guide for java socket programming courses. Now a days most of every one should known about socket programming because interaction among different vendors. thanks for sharing useful information
Embedded socket programming training courses
Thanks a lot for this detail about socket programming in java. As beginner i was looking for this socket programming guide and information. You have defined it so well as it is so important for making program run. Keep sharing.
This is very useful article! Yet as beginner i just know about socket programming that it is Unix input/output (I/O) program follows a model usually known to as Open-Read-Write-Close. Before a person procedure can execute I/O functions, it phone calls Available to specify and acquire authorizations for the data file or system to be used. But you have provided a great code here that i can use in my coming project, just loved it, Thanks for sharing!
Before reading this, I was feeling socket programming in java is very difficult and I only stuck to python. But now, after reading this, I can also do socket programming in java. Thank you so much.
Really Great.Thanks
http://stackoverflow.com/questions/25031090/telnet-is-not-recognized-as-internal-or-external-command
plus in windows have to print without “$’.
plus in “Close socket” section you forgot s.
Author should print: s_in.close();
It helped me a lot ….NICE WORK
if i have multiple servers and each of it wants to send messages to other server then how would i do that.
thank you for this great website, I am just curious if I could fix conn.getInetAddress() statically on the client side??
great tutorial,, can you provide some hint for multicast in java socket programming ,can it be done with the help of threads??
Wow!!!! so excellent Web site. I need this for my new Java project.
Thanks a lot for this gold code. Very Cool.
see my blog also
Can u please explain how to check whether the sent message from TCP is received or not?
Hi, I tried connect a socket with multiple threads and using bruteforce.After 5-6 minute I got an exception “java.lang….to many open socket” ….can anyone help me.
thank you very much, i got a lot of knowledge from your website.
Thank you for a great tutorial on Java Sockets, so many of the tutorials that I found previously used lots of deprecated functions and classes. Also, I like that you built up the client file talking to an existing server (google) instead of relying on the user to create a working server and client simultaneously. Excellent pedagogy.
Helped a great deal!!
Many Thanks :)
Hi,
It is very useful.
I am making a proxy server using socket connection.
I want to add features in the proxy server like redirecting the browser to a login page if the user has not login. When user has login, it will be able to do browsing but when a certain time is exhausted, it is again redirected to a login page. When the user login again, the user will be able to continue from the page its was redirected.
I am stuck in the initial phase where I want to redirect user to lets say google.com.
I have typed http://www.yahoo.com and trying to redirect to http://www.google.com
I am getting following error
“Connected
HTTP/1.1 302 Found
Location: http://www.google.co.in/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=17a9d84072c36e0d:FF=0:TM=1351049168:LM=1351049168:S=fNiwPQZ0kpEqwhYX; expires=Fri, 24-Oct-2014 03:26:08 GMT; path=/; domain=.google.com
Set-Cookie: NID=65=JmrJPskllovAw2EMLuiQWUDmfV3WxU_PaU_lXDiVtfN5ag8BFALND6XkhpZ8Y5mx4qtt-86Bo1AAvohsSkZ5H7fZ4Iaerbc8TaTsagrirb-nBmKi3M97qiPhnIZzkBcb; expires=Thu, 25-Apr-2013 03:26:08 GMT; path=/; domain=.google.com; HttpOnly
P3P: CP=”This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.”
Date: Wed, 24 Oct 2012 03:26:08 GMT
Server: gws
Content-Length: 221
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
302 Moved
302 Moved
The document has moved
here.
p://www.googHTTP/1.0 400 Bad requestCache-Control: no-cacheConnection: closeContent-Type: text/html400 Bad requestYour browser sent an invalid request.IO Exception Software caused connection abort: recv failed
java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at proxyservers.dwgold.ProxyThread.run(ProxyThread.java:50)
Java Result: 1″
This is the code base
import java.net.*;
import java.io.*;
import java.lang.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
class ProxyThread extends Thread {
Socket incoming, outgoing;
boolean toServer;
ProxyThread(Socket in, Socket out, boolean toserver) {
incoming = in;
outgoing = out;
toServer = toserver;
}
// Overwritten run() method of thread,
// does the data transfers
@Override
public void run() {
byte[] buffer = new byte[60];
int numberRead = 0;
String meta = “”;
try {
if (toServer) {
OutputStream toClient;
InputStream fromClient;
toClient = outgoing.getOutputStream();
fromClient = incoming.getInputStream();
while (true) {
String response;
BufferedReader inReader = null;
inReader = new BufferedReader(new InputStreamReader(fromClient));
while ((response = inReader.readLine()) != null) {
System.out.print(“” + response);
buffer = response.getBytes();
toClient.write(buffer, 0, response.getBytes().length);
}
// numberRead = fromClient.read(buffer, 0, 50);
//String browserRequest = new String(buffer, 0, 50);
//meta = browserRequest;
// if (toServer) {
// System.out.print(“” + meta);
// } else {
// System.out.print(“” + meta);
// }
// forward the response from the proxy to the server
if (numberRead == -1) {
incoming.close();
outgoing.close();
}
//System.out.println(“Forwarding request to server”);
//toClient.write(buffer, 0, numberRead);
}
} else {
String url = “www.google.com”;
//URL server = new URL(url);
//HttpURLConnection connection = (HttpURLConnection) server.openConnection();
//connection.connect();
Socket redirect = new Socket();
PrintWriter outWriter = null;
redirect.connect(new InetSocketAddress(url, 80));
System.out.println(“Connected “);
//writer for socket
outWriter = new PrintWriter(redirect.getOutputStream(), true);
//Send message to server
String message = “GET / HTTP/1.1\r\n\r\n”;
outWriter.println(message);
//writer for socket
outWriter = new PrintWriter(redirect.getOutputStream(), true);
InputStream fromClient = redirect.getInputStream();
OutputStream toClient = outgoing.getOutputStream();
while (true) {
numberRead = fromClient.read(buffer, 0, 50);
String browserRequest = new String(buffer, 0, 50);
meta = browserRequest;
if (toServer) {
System.out.print(“” + meta);
} else {
System.out.print(“” + meta);
}
// forward the response from the proxy to the server
if (numberRead == -1) {
redirect.close();
outgoing.close();
}
//System.out.println(“Forwarding request to server”);
toClient.write(buffer, 0, numberRead);
}
// readResponse(fromClient, toClient);
}
} catch (UnknownHostException e) {
System.err.println(“Don’t know about host : “);
System.exit(1);
} catch (IOException e) {
System.out.println(“IO Exception ” + e.getMessage());
e.printStackTrace();
System.exit(1);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(“Array Exception ” + e.getMessage());
e.printStackTrace();
System.exit(1);
}
}
}
The else case is where the socket listen to the request going from local system to the remote system and the if case is where the socket listen to the incoming response.
Please guide
Very useful, thanks ! Loved your website :)