Internet protocol (IP) version 4 is the predominant protocol used at the network layer of the Internet and most other distributed systems. It is responsible for the routing of packets from the source to the destination in a network.
It is said to offer best-effort delivery as there is no guarantee that all packets will reach the destination. For instance, there might be a network failure or a buffer at a node might overflow so packets would be dropped. Also, packets might take different routes through the network resulting in them arriving out of order at the destination. Only the IP header has a checksum to ensure validity so any corrupted data in an IP packet would go undetected.
There are two alternative transport layer protocols (until the newer IP version 6 becomes more commonplace) based on IP that are widely used by application programs:
Transmission control protocol (TCP) which starts by establishing a bidirectional connection between the source and destination. It subdivides an arbitrarily long stream of data into IP packets and assigns a sequence number to each so that they can be reassembled at the destination in the correct order. The destination acknowledges received packets and any packet not acknowledged within a specified time is retransmitted. Furthermore, the rate of transmission is controlled by the source to ensure that the destination is not overwhelmed. A checksum is used to drop any packet that is found to have corrupted data (and so would get retransmitted).
User datagram protocol (UDP) which is a simple protocol layered on top of IP that avoids the overhead of establishing a connection. It includes a short header that holds the source and destination ports and an optional data checksum, followed by the data, all together in a single IP packet called a datagram. Since IP packets are limited in size (to 64kbyte), this imposes a limit on the size of a single UDP message, which a platform might restrict to be as little as 8kbyte. It makes no guarantee that the data will be successfully transmitted, occasionally messages might get dropped so it is up to the application layer to ensure reliability if required.
Whereas IP supports communication between one computer and another, both the transport layer protocols TCP and UDP use ports to support communication between individual processes on computers, so several processes can be using network communication concurrently on a computer. Communication via a port is represented by a socket, and a port can only be bound to a single socket at a time.
TCP is used for point-to-point communication between a source (client) and a destination (server) that requires a reliable connection, ensuring all the data actually get transmitted and received in the same order as sent, even if this imposes a delay on the transmission. As such TCP is used for many application level protocols, where the integrity of the communication is essential:
Hypertext transfer protocol (HTTP) which is used for making requests to and receiving replies from web servers on port 80 (note since HTTP is so widely used by applications, languages such as Java provide API classes such as URL for convenient HTTP communication without having to deal with TCP directly),
File transfer protocol (FTP) which is used to initiate the transfer of a file on port 21,
Simple mail transfer protocol (SMTP) which is a basic protocol for sending e-mail messages on port 25,
Telnet which provides access to a remote computer by a terminal session on port 23.
UDP has much less overhead than TCP, and is used for the communication of small independent data packets that are not guaranteed to be delivered nor in order. UDP would typically be used by the application layer for a service where it is more important to keep efficient transmission with up to date messages arriving than it is to ensure each message is successfully transmitted.
UDP is used for application level protocols such as:
Domain name system (DNS) which is used to resolve host names into IP addresses, such as the host name cache.aut.ac.nz into the IP address 156.62.1.12,
Voice over IP (VOIP) which is used to transmit streams of digitized voice samples.
The java.net package in Java provides the Socket and ServerSocket classes for TCP communication back and forth between a client and a server using a reliable connection. The client and server each bind a socket to their end of the connection, and then read from an input stream and write to an output stream of their respective socket.
A TCP client can be implemented in Java by the following steps:
Initiate the connection A client requests a connection by creating a Socket object specifying the host name (or IP address) and the port:
Socket socket = new Socket(HOST_NAME, HOST_PORT);
Obtain streams Input and/or output streams are obtained from the socket and are layered with appropriate filtering streams:
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Communicate The client uses the streams to communicate with the server using an agreed protocol:
out.println(clientRequest); // non-blocking
String serverResponse = in.readLine(); // blocking
Close Connection When completed the client cleans up by closing the streams and then the socket:
out.close();
in.close();
socket.close();
A TCP server must be running on the host machine before any client requests a connection. Implementing a server is similar to a client but just requires a few extra steps since a typical server should be able to handle multiple clients concurrently:
Create a server socket
The server states its intention to listen on a specific port by creating a ServerSocket object for that port. It might be configured with a timeout:
ServerSocket serverSocket = new ServerSocket(PORT);
serverSocket.setSoTimeout(30000); // 30 second timeout
Listen for connections The ServerSocket method accept is called to block the main server thread until a request is received. Typically the resulting Socket is passed to a separate thread for handling the communication so that the main server thread can continue listening for other clients:
Socket socket = serverSocket.accept();
Thread thread = new Thread(...);
thread.start();
Obtain streams Input and/or output streams are obtained from the socket and are layered with appropriate filtering streams:
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Communicate The server thread uses the streams to communicate with the client using an agreed protocol:
String clientRequest = in.readLine(); // blocking
out.println(serverResponse); // non-blocking
Close Connection When the communication has completed with that client the server cleans up by closing the streams and then the socket (if the server itself is completed then it also closes the server socket):
out.close();
in.close();
socket.close();