1°/ Interactive client in a console

 

  • We assume that the client executes within a terminal, and the requests are given bu the user via the keyboard.
  • From user's point of view, sending a request consists in typing a line that represents what he wants to ask to the server. In the followng template, the line format for the user is : request_name param1 param2 ... (NB : it is quite simialr to the format of the real request that is sent by the client, see below)
  • From the client's point of view, this line must be analyzed and translated into a request to the server.
  • The format of the request to the server is : req_identifier client_id param1 param2 ...
  • We assume that the identifier of each request is a number 1, 2, ... except the "quit" request that means the client wants to disconnect from the server.
  • The client id is a unique identifier that is sent to the client juste after the acception of the connection.
  • We also assume that all communications are done using text (=> using PrintStream and BufferedReader), in order to facilitate debug and to comply with the fact that embedded systems are not necessarily able to use Java to communicate.
  • Finally, we assume that the client application is organized in 2 classes:  Client and ClientTCP

 

Client.java :

import java.net.*;
import java.io.*;
 
class Client {
 
  public static void usage() {
    System.err.println("usage : java Client ip_server port");
    System.exit(1);
  }
 
  public static void main(String[] args) {
 
    if (args.length != 2) {
      usage();
    }
 
    ClientTCP client = null;
    try {
      int port = Integer.parseInt(args[1]);
      client = new ClientTCP(args[0], port);
      client.requestLoop();
    }
    catch(NumberFormatException e) {
      System.err.println("invalid port number");
      System.exit(1); 
    }
    catch(IOException e) {
      System.err.println("cannot communicate with server");
      System.exit(1);
    }
  }
}
 

 

ClientTCP.java :

import java.io.*;
import java.net.*;
import java.util.*;
 
class ClientTCP  {
 
  Socket sockComm;
  BufferedReader br; PrintStream ps;
  String id; // the client id sent by the server with request 0
 
  public ClientTCP(String serverIp, int serverPort) throws IOException {
    sockComm = new Socket(serverIp, serverPort);
    ps = new PrintStream(sockComm.getOutputStream());
    br = new BufferedReader(new InputStreamReader(sockComm.getInputStream()));
    // get my id
    id = br.readLine();
  }
 
  public void requestLoop() throws IOException { 
 
    boolean stop = false;
    String reqLine = null;
    BufferedReader consoleIn = null;
    String[] reqParts = null;
 
    consoleIn = new BufferedReader(new InputStreamReader(System.in));
 
    while (!stop) {
      System.out.print("Client> ");
      reqLine = consoleIn.readLine();
      reqParts = reqLine.split(" ");
 
      if ("req1".equals(reqParts[0])) {
        String req = "1 "+id+" ";
        // adding to req parameters obtined from reqParts[1] reqParts[2], ...)
        ps.println(req);
        String answer = br.readLine();
        // processing answer
      }
      else if ("req2".equals(reqParts[0])) {
        String req = "2 "+id+ " ";
        // adding to req parameters obtained from reqParts[1] reqParts[2], ...)
        ps.println(req);
        String answer = br.readLine();
        // processing answer
      }
      /* etc. with other requests */
       else if ("quit".equals(reqParts[0])) {
        ps.println("quit");
        stop = true;
      }
    }
  }
}
 


2°/ Server with a single client at a time.

  • As for the client, we assume that the server is composed of two classes : Server and ServerTCP

Server.java :

import java.net.*;
import java.io.*;
 
class Server {
 
  public static void usage() {
    System.err.println("usage : java Server port");
    System.exit(1);
  }
 
  public static void main(String[] args) {
 
    if (args.length != 1) {
      usage();
    }
 
    ServerTCP server = null;
    try {
      int port = Integer.parseInt(args[0]);
      server = new ServerTCP(port);
      server.mainLoop();
    }
    catch(NumberFormatException e) {
      System.err.println("invalid port number");
      System.exit(1);
    }
    catch(IOException e) {
      System.err.println("cannot communicate with client");
      System.exit(1);
    }
  }
}

 

 ServerTCP.java :

import java.io.*;
import java.net.*;
import java.util.*;
 
class ServerTCP  {
 
  BufferedReader br; 
  PrintStream ps;
  ServerSocket sockConn;
  Socket sockComm;
  int idClient;
  // other attributes, usefull to process request
 
  public ServerTCP(int port) throws IOException {
    idClient = 0;
    sockConn = new ServerSocket(port);
  }
 
  public void mainLoop() throws IOException {
    while(true) {
      sockComm = sockConn.accept();
      try {
        br = new BufferedReader(new InputStreamReader(sockComm.getInputStream()));
        ps = new PrintStream(sockComm.getOutputStream());
        idClient += 1;
        ps.println(idClient); // sending its id to the client
        requestLoop();
        br.close(); // close stream => close connection
        ps.close();
      }
      catch(IOException e) {
        System.out.println("client disconnected");
      }
    }
  }
 
  public void requestLoop() throws IOException {
 
    String req = "";
    boolean stop = false;
 
    while(!stop) {
      req = br.readLine();
      if (req == null) return; // stop loop : suppose that client disconnected
      if (req.isEmpty()) continue; // empty req => do nothing special
      String[] reqParts = req.split(" ");
 
      if ("1".equals(lst[0])) {
        if (reqParts.length != ...) { // check number of params
          ps.println("ERR invalid number of paramters");
        }
        else {
          processRequest1(reqParts[1], ... ); // replace ... by a list of reqParts[x]
        }
      }
      else if ("2".equals(lst[0])) {
        if (reqParts.length != ...) {
          ps.println("ERR invalid number of parameters");
        }
        else {
          processRequest2(reqParts[1], ... ); // replace ... by a list of reqParts[x]
        }
      }
      /* etc. with other requests */
      else if ("quit".equals(lst[0])) {
        stop = true;
      }
    }
  }  
 
  public void processRequest1(String idStr, String param1, String param2, ...) throws IOException {
    int id;
    try {
      id = Integer.parseInt(idStr);
      // add here other params to translate into numbers
    }
    catch(NumberFormatException e) { 
      ps.println("ERR invalid type of parameter");
      return; 
    }
    if (id != idClient) {
      ps.println("ERR invalid id");
      return; 
    }
    // add here other tests on other parameters
 
    // if all ok, 
    ps.println("OK");
    // process the request and send the result to the client
  }
 
  // etc. with other processRequestX() methods
}