Socket : services

 

un serveur HTTP simplissime

Source de MonSimpleServeurHttp.java
import java.io.*;
import java.net.*;
import java.util.zip.*;
public class MonSimpleServeurHttp {
  public static void main(String args[]) {
    try {
      int port = 80;
      if (args.length == 1)
        port = Integer.parseInt(args[0]);
      ServerSocket sockServ = new ServerSocket(port);
      System.out.println("start Simple Http Server :\n " 
      + "ecoute sur port " + port);     
      for(;;) {
        Socket sockClient = sockServ.accept();
        System.out.println("connection de :"  + sockClient);     
        BufferedReader sockIn = new BufferedReader(
                    new InputStreamReader(sockClient.getInputStream()));
        PrintWriter sockOut = new PrintWriter(sockClient.getOutputStream());   
        try {
          String reqLine  = sockIn.readLine();
          while ((reqLine != null)&& (reqLine.length() == 0)) 
            reqLine = sockIn.readLine();
          reqLine.trim();
          if (reqLine.indexOf("GET") != 0)
            throw new DataFormatException("requete autre que GET"); 
          String fileName = reqLine.substring(3,reqLine.length()).trim()
                                                + " ";
          int endOfFileName = fileName.indexOf(" ");
          fileName = fileName.substring(0, endOfFileName);
          File file = new File(fileName);
          if (! (file.exists()&&file.isFile()&&file.canRead()) )
            throw new FileNotFoundException("fichier inexistant"
                                          + " ou inaccessible");
          sockOut.print("HTTP/1.0 200 OK\n");          
          sockOut.print("Content-Type: text/plain\n"); 
          FileReader fileIn = new FileReader(file);
          long len= file.length();
          sockOut.print("Content-length : "+len);    
          sockOut.print("\n");    
          char[] buffer = new char[1024];
          int nombreLu;
          while ((nombreLu = fileIn.read(buffer,0,1024)) != -1)
            sockOut.write(buffer,0,nombreLu);
          fileIn.close();
        }
        catch (DataFormatException e) {
          sockOut.print("HTTP/1.0 400 "+e.getMessage()+"\n");             
        }
        catch (FileNotFoundException e) {
          sockOut.print("HTTP/1.0 404 "+e.getMessage()+"\n");          
        }
        finally {
          sockOut.print("\n");        
          sockOut.close();    
          sockIn.close();     
          sockClient.close();  
        } 
      }
    }      
    catch (Exception e) {
      System.err.println(e);
      System.err.println("Usage: java MonSimpleServeurHttp [<port>]");
    }
  }
}
Un fichier essai

EXECUTION
sur console 1 :
$ cat essai
fichier essai
de 2 lignes
$ java MonSimpleServeurHttp 8000
start Simple Http Server :
 ecoute sur port 8000

sur console 2 :
$ telnet -e $ localhost 8000
Telnet escape character is '$'.
Trying 127.0.0.1...
Connected to localhost.
Escape character is '$'.
GET essai
HTTP/1.0 200 OK
Content-Type: text/plain
Content-length : 26
fichier essai
de 2 lignes
Connection closed by foreign host.

sur console 1 :
connection de :Socket[addr=/127.0.0.1,port=1048,localport=8000]

Les lignes de la classe :


serveur HTTP multi-connection

Source de ServerPlusieursConnections.java
import java.io.*;
import java.net.*;
public class ServerPlusieursConnections {
  private int maxConnection = 0;
  private int nbreConnection = 0;
  private ServerSocket serveurSock = null;
  private int modeLent = 0;
  public static void main(String args[]) {
    try {
      if ((args.length < 2) || (args.length > 3))
        throw  new IllegalArgumentException("Usage: java "
          +"ServerPlusieursConnections port maxconnection [mode_lent]");
      int port = Integer.parseInt(args[0]);
      int maxConnection = Integer.parseInt(args[1]);
      int modeLent = 0;
      if (args.length == 3)
        modeLent = Integer.parseInt(args[2]); // 500 !
      ServerPlusieursConnections server = 
        new ServerPlusieursConnections(port, maxConnection, modeLent);
      server.go();
    }  
    catch (Exception e) {
      System.err.println(e);
    }
  }
  public ServerPlusieursConnections(int port, int maxConnection, 
         int modeLent) throws IOException {    
    serveurSock = new ServerSocket(port);
    this.maxConnection = maxConnection;
    this.nbreConnection = 0;
    this.modeLent = modeLent;
  }
  public void go() throws IOException {
    for(;;) {
        Socket sockClient = serveurSock.accept();
        addConnection(sockClient);     
    }
  }
  protected synchronized void addConnection(Socket sockClient) {
    if (nbreConnection >= maxConnection) {
      try {
        PrintWriter out = new PrintWriter(sockClient.getOutputStream());
        out.print("connection refusee\n");
        out.close();    
        sockClient.close();  
      }  
      catch (Exception e) {
        System.err.println(e);
      }
    }
    else {
      nbreConnection++;
      Connection connect = new Connection(sockClient);
      System.out.println("connection de : " + sockClient);
      connect.start();
    }
  }
  protected synchronized void finConnection() {
    nbreConnection--;
  }
  private class Connection extends Thread {
    private Socket sockClient = null;
    public Connection(Socket sockClient) {
      super("ServerConnection : " 
           + sockClient.getInetAddress().getHostAddress() 
           + " : " + sockClient.getPort());
      this.sockClient = sockClient;
    }
    public void run() {
      try {
        boolean Ok = true;
        BufferedReader sockIn = new BufferedReader(
                new InputStreamReader(sockClient.getInputStream()));
        PrintWriter sockOut = new PrintWriter(sockClient.getOutputStream());
        String requete = sockIn.readLine();
          File file = null;
        if (requete == null)
          Ok = false;
        else {
          requete.trim();
          if (requete.indexOf("GET") != 0)
            Ok = false;
          else {
            String nomFichier = requete.substring(3,
                                  requete.length()).trim()+" ";
            int finNomFichier = nomFichier.indexOf(" ");
            nomFichier = nomFichier.substring(0, finNomFichier);        
            file = new File(nomFichier);
            if (! (file.exists()&&file.isFile()&&file.canRead()) )
              Ok = false;
          }
        }
        if (Ok) {
          sockOut.print("HTTP/1.0 200 Ok\n");          
          sockOut.print("Content-Type: text/plain\n"); 
          FileReader flotFichier = new FileReader(file);
          long longueur= file.length();
          sockOut.print("Content-length : "+longueur);    
          sockOut.print("\n");    
          char car=0;
          for ( int i = 0; i < longueur; i++) {
            car= (char)flotFichier.read();
            sockOut.print(car);
            if (modeLent != 0) {
              sockOut.flush();
              sleep((int)(Math.random()*modeLent));
            }
          }
          flotFichier.close();
        }
        else {
          sockOut.print("HTTP/1.0 400 Not Found\n");          
        }
        sockOut.print("\n");
        sockOut.close();    
        sockIn.close();  
        System.out.println("          fin de : " + sockClient);   
        sockClient.close();  
      }    
      catch (Exception e) {
        System.err.println(e);
      }
      finally {
        finConnection();
      }
    } 
  }
}

EXECUTION
sur console 1 :
$ java ServerPlusieursConnections 8000 2 500

sur console 2 :
$ telnet -e $ localhost 8000
Telnet escape character is '$'.
Trying 127.0.0.1...
Connected to localhost.
Escape character is '$'.
GET essai
HTTP/1.0 200 OK
Content-Type: text/plain
Content-length : 26
fichier essai
de 2 lignes
Connection closed by foreign host.

sur console 3 :
$ telnet
.....

sur console 4 :
$ telnet -e $ localhost 8000
Telnet escape character is '$'.
Trying 127.0.0.1...
Connected to localhost.
Escape character is '$'.
connection refusee
Connection closed by foreign host.

sur console 1 :
connection de : Socket[addr=/127.0.0.1,port=1065,localport=8000]
connection de : Socket[addr=/127.0.0.1,port=1066,localport=8000]
          fin de : Socket[addr=/127.0.0.1,port=1065,localport=8000]
          fin de : Socket[addr=/127.0.0.1,port=1066,localport=8000]

Les lignes de la classe :

serveur multi-connections "connectées"

Source de ServerProphete.java
import java.io.*;
import java.net.*;
import java.util.*;
public class ServerProphete {
  private ArrayList<String> listProphetie = null;
  private ServerSocket serveurSock = null;
  static int port = 6666;
  public static void main(String args[]) {
    try {
      ServerProphete server =  new ServerProphete();
      server.go();
    }  
    catch (Exception e) {
      System.err.println("erreur server : "+e.getMessage());
    }
  }
  public ServerProphete() throws IOException {    
    serveurSock = new ServerSocket(port);
    listProphetie = new ArrayList();
    SaisieProphetie saisie = new SaisieProphetie();
    saisie.start();
  }
  public void go() throws IOException {
    for(;;) {
      Socket sockClient = serveurSock.accept();
      System.out.println("connection de : "+sockClient);
      Connection connect = new Connection(sockClient);
      connect.start();   
    }
  }
  private class Connection extends Thread {
    private Socket sockClient = null;
    public Connection(Socket sockClient) {
      this.sockClient = sockClient;
    }
    public void run() {
      DataInputStream sockDataIn = null;
      OutputStream sockOut = null;
      byte[] buffer = new byte[1024];
      String prophetie = null;
      try {
        sockDataIn = new DataInputStream(socket.getInputStream());
        sockOut = socket.getOutputStream();
        while (true) { 
          int i = sockDataIn.readInt();
          synchronized(listProphetie) {
            try {
              prophetie = listProphetie.get(i);
            } catch (IndexOutOfBoundsException e) {
              prophetie ="";
            }      
          }
          prophetie = prophetie+"\n";
          buffer = prophetie.getBytes();
          sockOut.write(buffer, 0, prophetie.length());
          sockOut.flush();    
        }
      } catch (IOException e) {
        System.out.println("erreur du socket : "+sockClient+"\n"+e.getMessage());
      } finally {
        System.out.println("fin du socket : "+sockClient);
        try {
          sockDataIn.close();
          sockOut.close();
          sockClient.close();
        } catch (IOException e) {
          System.out.println("erreur grave du socket : "+sockClient+"\n"+e.getMessage());
        } 
      }
    }     
  }
  private class SaisieProphetie extends Thread {
    public void run() {
      BufferedReader console = null;
      String message = null;
      try {
        console = new BufferedReader(new InputStreamReader(System.in));
        while (true)  {
          message = console.readLine();
          synchronized(listProphetie) {
            listProphetie.add(message);
          }
        }  
      } catch (IOException e) {
        System.out.println("erreur fatale "+e.getMessage());
      }
    }  
  }
}

Source de ClientDisciple.java
import java.io.*;
import java.net.*;
import java.util.*;
public class ClientDisciple {
  private String hote;
  static int port = 6666;
  private boolean continuer = true;
  public static void main(String[] args) 
  throws IOException {
    try {
      if (args.length != 1) 
      throw new IllegalArgumentException("Usage: java "
        +"ClientDisciple  hote ");
      String hote = args[0];
      ClientDisciple client = new ClientDisciple(hote);  
      client.go();
    } catch (Exception e) {
      System.out.println("arret du client \n  erreur : "+e.getMessage());
    }
  }
  public ClientDisciple(String hote) {
    this.hote = hote;
  }
  
  public void go() throws Exception {	  
    Socket socket = null;
    DataOutputStream sockDataOut = null;
    BufferedReader sockIn = null;
    Scanner scan = new Scanner(System.in);
    boolean continuer = true;
    String prophetie = null;
    try {
      socket = new Socket(hote, port);
      sockDataOut = new DataOutputStream(socket.getOutputStream());
      sockIn = new BufferedReader(new InputStreamReader
                                            (socket.getInputStream()));
    } catch (UnknownHostException e) {
      throw new Exception("hote non atteignable : "+hote+"\n"+e.getMessage());
    } catch (IOException e) {
      throw new Exception("connection impossible avec : "+hote+"\n"+e.getMessage());
    }   
    System.out.println("tapez q pour terminer, sinon un numero de prophetie"); 
    while (continuer) 
      if (scan.hasNextInt()) {
        try {
          sockDataOut.writeInt(scan.nextInt()-1);
          prophetie = sockIn.readLine();
          if (prophetie != null) 
            System.out.println("prophetie : "+prophetie);
          else {
        System.out.println("fermeture de la connection au serveur");
            continuer = false;
          }          
        } catch (IOException e) {
      System.out.println("impossible d'envoyer ou lire au serveur\n"+e.getMessage());
          continuer = false;
        }
      } else 
        if (scan.next().toLowerCase().equals("q"))
          continuer = false;
    sockDataOut.close();
    socket.close();
  }
}
EXECUTION
sur console 1 :
$ java ServerProphete 
Dieu est grand 
Le Chat aussi

sur console 2 :
$ java ClientDisciple localhost 
tapez q pour terminer, sinon un numero de prophetie 
2 
prophetie : Le Chat aussi 
1 
prophetie : Dieu est grand q $

Les lignes de la classe :

Select sur les Sockets:

exercices