Java Network Programming
Network programming involves writing programs that run on multiple devices (computers) connected through a network.
The java.net
package in J2SE's API includes classes and interfaces that provide low-level communication details. You can use these classes and interfaces directly to focus on solving problems without worrying about communication details.
The java.net
package supports two common network protocols:
TCP: TCP (Transmission Control Protocol) is a connection-oriented, reliable, byte-stream transport layer communication protocol. The TCP layer is situated above the IP layer and below the application layer. TCP ensures reliable communication between two applications and is commonly used with the Internet Protocol, referred to as TCP/IP.
UDP: UDP (User Datagram Protocol) is located in the transport layer of the OSI model. It is a connectionless protocol that provides datagrams for sending data between applications. Due to UDP's lack of reliability and connectionless nature, applications typically must tolerate some loss, errors, or duplicate packets.
This tutorial primarily covers the following topics:
Socket Programming: This is the most widely used network concept and has been explained in great detail.
URL Handling: This topic will be covered in a separate section. Click here for more detailed information on URL Handling in Java.
Socket Programming
Sockets use TCP to provide communication mechanisms between two computers. A client program creates a socket and attempts to connect to the server's socket.
When the connection is established, the server creates a Socket object. The client and server can now communicate by writing to and reading from the Socket object.
The java.net.Socket
class represents a socket, and the java.net.ServerSocket
class provides a mechanism for server programs to listen for clients and establish connections with them.
The following steps occur when establishing a TCP connection between two computers using sockets:
The server instantiates a ServerSocket object, indicating communication through a port on the server.
The server calls the
accept()
method of the ServerSocket class, which waits until a client connects to the server on the given port.While the server is waiting, a client instantiates a Socket object, specifying the server name and port number to request a connection.
The constructor of the Socket class attempts to connect the client to the specified server and port number. If communication is established, a Socket object is created on the client side for communication with the server.
On the server side, the
accept()
method returns a new socket reference on the server that is connected to the client's socket.
After the connection is established, communication can occur using I/O streams. Each socket has an output stream and an input stream. The client's output stream is connected to the server's input stream, and the client's input stream is connected to the server's output stream.
TCP is a bidirectional communication protocol, allowing data to be sent simultaneously through both data streams. The following are some classes that provide a set of useful methods for implementing sockets.
ServerSocket Class Methods
Server applications use the java.net.ServerSocket
class to obtain a port and listen for client requests.
The ServerSocket class has four constructors:
No. | Method Description |
---|---|
1 | public ServerSocket(int port) throws IOException <br> Creates a server socket bound to a specific port. |
2 | public ServerSocket(int port, int backlog) throws IOException <br> Creates a server socket with a specified backlog and binds it to the specified local port number. |
3 | public ServerSocket(int port, int backlog, InetAddress address) throws IOException <br> Creates a server socket with the specified port, listen backlog, and local IP address to bind to. |
4 | public ServerSocket() throws IOException <br> Creates an unbound server socket. |
If the ServerSocket constructor does not throw an exception, it means your application has successfully bound to the specified port and is listening for client requests.
Here are some common methods of the ServerSocket class:
No. | Method Description |
---|---|
1 | public int getLocalPort() <br> Returns the port on which this socket is listening. |
2 | public Socket accept() throws IOException <br> Listens for and accepts a connection to this socket. |
This is an English translation of the Chinese text provided.
Methods of the Socket Class
The java.net.Socket
class represents a socket that both the client and the server use to communicate with each other. A client obtains a Socket
object by instantiating it, while a server obtains a Socket
object from the return value of the accept()
method.
The Socket
class has five constructors.
| Number | Method Description |
| 1 | public Socket(String host, int port) throws UnknownHostException, IOException.
<br>Creates a stream socket and connects it to the specified port number on the named host. |
| 2 | public Socket(InetAddress host, int port) throws IOException
<br>Creates a stream socket and connects it to the specified port number at the specified IP address. |
| 3 | public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException.
<br>Creates a socket and connects it to the specified remote host on the specified remote port. |
| 4 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException.
<br>Creates a socket and connects it to the specified remote address on the specified remote port. |
| 5 | public Socket()
<br>Creates an unconnected socket with the system-default type of SocketImpl
. |
When the Socket
constructor returns, it does not simply instantiate a Socket
object; it actually attempts to connect to the specified server and port.
Below are some interesting methods, noting that both the client and the server have a Socket
object, so either the client or the server can call these methods.
| Number | Method Description |
| 1 | public void connect(SocketAddress host, int timeout) throws IOException
<br>Connects this socket to the server with a specified timeout value. |
| 2 | public InetAddress getInetAddress()
<br>Returns the address to which the socket is connected. |
| 3 | public int getPort()
<br>Returns the remote port to which this socket is connected. |
| 4 | public int getLocalPort()
<br>Returns the local port to which this socket is bound. |
| 5 | public SocketAddress getRemoteSocketAddress()
<br>Returns the address of the endpoint this socket is connected to, or null
if it is not connected. |
| 6 | public InputStream getInputStream() throws IOException
<br>Returns an input stream for this socket. |
| 7 | public OutputStream getOutputStream() throws IOException
<br>Returns an output stream for this socket. |
| 8 | public void close() throws IOException
<br>Closes this socket. |
Methods of the InetAddress Class
This class represents an Internet Protocol (IP) address. Below are some useful methods for socket programming:
| Number | Method Description |
| 1 | static InetAddress getByAddress(byte[] addr)
<br>Returns an InetAddress
object given the raw IP address. |
| 2 | static InetAddress getByAddress(String host, byte[] addr)
<br>Creates an InetAddress
based on the provided host name and IP address. |
| 3 | static InetAddress getByName(String host)
<br>Determines the IP address of a host, given the host's name. |
| 4 | String getHostAddress() <br>Returns the IP address string in textual representation. |
| 5 | String getHostName() <br>Gets the host name for this IP address. |
| 6 | static InetAddress getLocalHost() <br>Returns the local host. |
| 7 | String toString() <br>Converts this IP address to a String. |
Socket Client Example
The following GreetingClient is a client program that connects to a server via socket, sends a request, and waits for a response.
GreetingClient.java File Code:
// File name GreetingClient.java
import java.net.*;
import java.io.*;
public class GreetingClient
{
public static void main(String [] args)
{
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try
{
System.out.println("Connecting to host: " + serverName + ", port number: " + port);
Socket client = new Socket(serverName, port);
System.out.println("Remote host address: " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("Server response: " + in.readUTF());
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
Socket Server Example
The following GreetingServer program is a server-side application that uses a Socket to listen on a specified port.
GreetingServer.java File Code:
// File name GreetingServer.java
import java.net.*;
import java.io.*;
public class GreetingServer extends Thread
{
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run()
{
while(true)
{
try
{
System.out.println("Waiting for remote connection, port number: " + serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Remote host address: " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println("Client says: " + in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress() + "\nGoodbye!");
server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
int port = Integer.parseInt(args[0]);
try
{
Thread t = new GreetingServer(port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to me: " + server.getLocalSocketAddress() + "\nGoodbye!");
server.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
try {
Thread t = new GreetingServer(port);
t.run();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Compile the above two Java files and execute the following command to start the service, using port number 6066:
$ javac GreetingServer.java
$ java GreetingServer 6066
Waiting for remote connection, port number: 6066...
Open a new command window and execute the following command to start the client:
$ javac GreetingClient.java
$ java GreetingClient localhost 6066
Connecting to host: localhost, port number: 6066
Remote host address: localhost/127.0.0.1:6066
Server response: Thank you for connecting to me: /127.0.0.1:6066
Goodbye!