10 Socket Programming

Socket Programming

Objective

  • Introduce the concept of socket in communication.
  • Differentiate between TCP and UDP sockets.
  • Understand the TCP client/server architecture.
  • Employ the Socket and ServerSocket classes to build TCP client/server applications.

java javac DatagramSocket Socket ServerSocket Socket.close() Socket.getInputStream() Socket.getOutputStream() Socket.setSoTimeout() ServerSocket.accept() ServerSocket.close() ServerSocket.getInputStream() ServerSocket.getOutputStream()

Sockets

  • A virtual connection between machines is represented by sockets.

  • A socket is defined as an endpoint for communication. Thus, a pair of processes communicating over a network employ a pair of sockets one for each process.

  • A socket is identified by an Internet Protocol (IP) address concatenated with a port number.

  • In general, sockets use server/client architecture; where the server waits for incoming client requests by listening to a specified port. Once a request is received, the server accepts a connection from the client socket specified by its IP address and port number.

  • Servers implementing standard services listen to well-known ports which are identified by numbers below 1024. Examples of standard services with their associated ports are:

    ServicePort
    POP310
    Daytime13
    SSH22
    Telnet23
    SMTP25
    DNS53
    DHCP67, 68
    HTTP80
    HTTPS443
  • Client port numbers are assigned to some arbitrary numbers greater than 1024 and less than the maximum number of 65536.

  • For example, a web browser (client) with an IPv4 146.86.5.2 and port number 1625 wishes to retrieve a webpage from a web server with an IPv4 address 161.25.19.8 listening to port 80 (HTTP) can be illustrated by the following sequence diagram showing the two sockets:

  • If the two sockets are on the same machine, we can use localhost, but if they reside on different machines, we must specify the configured IP address.
  • For server/client applications, Java provides two common types of sockets:
    • Connection-oriented Transmission Control Protocol (TCP) sockets implemented using the Socket class with three connection steps: establish connection, data transfer, and terminate connection.
    • Connectionless User Datagram Protocol (UDP) sockets implemented using the DatagramSocket class with data transfer connection step only.

Example 1

In this example, the server waits for incoming client requests on port number 13 and responds with the current system daytime.

DaytimeClient.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
 
public class DaytimeClient {
  public static void main(String[] args) {
    try {
      // get a socket to the daytime service
      Socket daytime = new Socket("localhost", 13);
      System.out.println("Connected with server " + daytime.getInetAddress() +
                         ":" + daytime.getPort());
      // set the socket timeout just in case the server stalls
      daytime.setSoTimeout(2000);
      // read from the server
      BufferedReader reader =
          new BufferedReader(new InputStreamReader(daytime.getInputStream()));
      // display result on the screen
      System.out.println("Result: " + reader.readLine());
      // close the connection
      daytime.close();
    } catch (IOException e) {
      System.out.println("Error: " + e);
    }
  }
}
DaytimeServer.java
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
 
public class DaytimeServer {
  public static void main(String[] args) {
    try {
      // bind to service port so clients can access the daytime service
      ServerSocket server = new ServerSocket(13);
      System.out.println("Server waiting for client on port " +
                         server.getLocalPort());
      System.out.println("Daytime service started...");
      for (;;) {
        // get the next TCP Client
        Socket nextClient = server.accept();
        // display connection details
        System.out.println("Receiving request from " +
                           nextClient.getInetAddress() + ":" +
                           nextClient.getPort());
        // write the current time to the client socket
        PrintWriter output =
            new PrintWriter(nextClient.getOutputStream(), true);
        output.println(LocalDateTime.now());
        // close connection
        nextClient.close();
        server.close();
      }
    } catch (IOException e) {
      System.out.println("Error: " + e);
    }
  }
}

Compile the client/server application using:

javac DaytimeClient.java DaytimeServer.java

Run the server, then use another window to run the client:

java DaytimeServer
java DaytimeClient

You must run the server program before the client program so that the server will be listening for any connection requests from the client.

Exercise 1

Modify the Example 1 server/client Daytime application to allow the server to handle concurrent client requests, that is, a multi-threaded service.

Exercise 2

Develop a multi-threaded TCP server/client Piong application in which the server replies with pong! when it receives ping?, closes the connection when it receives bye, and replies with again? for any other request. The client reads requests from the user and sends them the server.

Exercise 3

Develop a multi-threaded TCP server/client Quicksum application in which the server accepts a client’s connection for a duration of 1 minute. During that time, the client will be continuously requested to add three random integer numbers sent by the server. When the alloted time is up, the server displays to the client the number of its successful answers.

Hint: To get the system’s current time in milliseconds, use the static method System.currentTimeMillis().