Outils pour utilisateurs

Outils du site


lang:java:net:client_serveur

TCP

Si le but est de faire passer du texte, on pourra prendre un Charset de UTF-8. Par contre, pour faire transiter de la donnée brute, il faut laisser la valeur par défaut (windows-1252 probablement).

Méthode avec l'API de base

Serveur texte compatible UTF-8

ServeurTCP.java
package org.llgc;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
 
public class ServeurTCP
{
  private static final int PORT = 9632;
 
  public static void main (String[] args)
  {
    try (ServerSocket server = new ServerSocket (PORT);)
    {
      System.out.println ("en attente de connexion");
      while (true)
      {
        // Attente du client
        Socket client = server.accept ();
        client.setTcpNoDelay(true); // pas de délai ACK
        try (
            BufferedReader entree = new BufferedReader (
                new InputStreamReader (client.getInputStream (), Charset.forName ("UTF-8")));
            PrintStream ps = new PrintStream (client.getOutputStream (), false, "UTF-8"))
        {
          System.out.println ("connexion établie avec " + client.getInetAddress ());
 
          while (true)
          {
            // Lecture du message du client
            String message = "";
            message = entree.readLine ();
            System.out.println (message);
            if (message == null)
            {
              break;
            }
 
            // Envoie du message au client
            ps.println (message);
            if (message.equals ("GoodBye"))
              break;
          }
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
      return;
    }
  }
}

Serveur binaire

ServeurTCP.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.io.Reader;
 
public class ServeurTCP
{
  private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
  public static String bytesToHex(byte[] bytes, int numCharsRead) {
    char[] hexChars = new char[numCharsRead * 3];
    for ( int j = 0; j < numCharsRead; j++ ) {
      int v = bytes[j] & 0xFF;
      hexChars[j * 3] = hexArray[v >>> 4];
      hexChars[j * 3 + 1] = hexArray[v & 0x0F];
      hexChars[j * 3 + 2] = ' ';
    }
    return new String(hexChars);
  }
 
  public static Integer tryParse(String text) {
    try {
      return Integer.parseInt(text);
    } catch (NumberFormatException e) {
      return null;
    }
  }
 
  public static void main (String[] args)
  {
    if (args.length != 1)
    {
      System.out.println("utilisation : ServeurTCP port");
      return;
    }
    Integer port = tryParse(args[0]);
    if (port == null)
    {
      System.out.println("Numéro de port incorrect");
      return;
    }
    try (ServerSocket server = new ServerSocket (port);)
    {
      System.out.println ("en attente de connexion");
      while (true)
      {
        // Attente du client
        Socket client = server.accept ();
        client.setTcpNoDelay(true);
        try (
            InputStream stream = client.getInputStream ())
        {
          System.out.println ("connexion étalie avec " + client.getInetAddress ());
 
          byte[] charArray = new byte[8 * 1024];
 
          while (true)
          {
            System.out.println ("Lecture...");
            // Lecture du message du client
            int numCharsRead = stream.read(charArray, 0, charArray.length);
            if (numCharsRead == -1)
            {
              break;
            }
            System.out.println (bytesToHex(charArray, numCharsRead));
           }
        }
        catch (java.net.SocketException e)
        {
            System.out.println ("Fin rapide avec " + client.getInetAddress ());
        }
      }
    }
    catch (Exception e)
    {
      e.printStackTrace();
      return;
    }
  }
}

Client

Le client maintient en temps réel la connexion avec le serveur.

ClientTCP.java
package org.llgc;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
 
public class ClientTCP
{
  private static final int PORT = 9632;
  private static final String SERVER_NAME = "localhost";
 
  public static void main (String[] args)
  {
    InetAddress adr;
    try
    {
      adr = InetAddress.getByName (SERVER_NAME);
    }
    catch (UnknownHostException e)
    {
      e.printStackTrace ();
      return;
    }
 
    try (Socket server = new Socket (adr, PORT);
        BufferedReader clavier = new BufferedReader (new InputStreamReader (System.in, Charset.forName ("UTF-8")));
        BufferedReader entree = new BufferedReader (
            new InputStreamReader (server.getInputStream (), Charset.forName ("UTF-8")));
        PrintStream ps = new PrintStream (server.getOutputStream (), false, "UTF-8"))
    {
      server.setTcpNoDelay(true); // pas de délai ACK
      while (true)
      {
        String message = clavier.readLine ();
        if (message == null)
        {
          break;
        }
 
        ps.println (message);
 
        // Lecture du message du client
        System.out.println (entree.readLine ());
        if (message.equals ("GoodBye"))
          break;
      }
    }
    catch (IOException e)
    {
      e.printStackTrace ();
      return;
    }
  }
}

Avec HttpComponents d'Apache

Client

Commencez par créer un nouveau Java Project, et installer la librairie HttpClient 4.5.2 (GA), Archive. Dans cet exemple, il sera nécessaire d'utiliser les librairies httpclient-4.5.2.jar, httpcore-4.4.4.jar et commons-logging-1.2.jar.

Ici, on ne maintient pas la connexion avec le serveur. On ne fait que des requêtes GET/POST.

Client.java
package org.llgc;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
 
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
 
public class Client {
  public static void main(String[] args) throws IOException {
    try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
      // GET
      HttpGet httpGet = new HttpGet("http://httpbin.org/get");
      try (CloseableHttpResponse response1 = httpclient.execute(httpGet)) {
        System.out.println(response1.getStatusLine());
        HttpEntity entity1 = response1.getEntity();
        System.out.println(entity1.getContentType());
        System.out.println(new BufferedReader(new InputStreamReader(entity1.getContent())).lines().parallel()
            .collect(Collectors.joining("\n")));
        EntityUtils.consume(entity1);
      }
 
      // POST
      // Avec deux valeurs (username et password) dans le formulaire.
      HttpPost httpPostForm = new HttpPost("http://httpbin.org/post");
      List<NameValuePair> nvps = new ArrayList<NameValuePair>();
      nvps.add(new BasicNameValuePair("username", "vip"));
      nvps.add(new BasicNameValuePair("password", "secret"));
      httpPostForm.setEntity(new UrlEncodedFormEntity(nvps));
      try (CloseableHttpResponse response2 = httpclient.execute(httpPostForm)) {
        System.out.println(response2.getStatusLine());
        HttpEntity entity2 = response2.getEntity();
        System.out.println(entity2.getContentType());
        System.out.println(new BufferedReader(new InputStreamReader(entity2.getContent())).lines().parallel()
            .collect(Collectors.joining("\n")));
        EntityUtils.consume(entity2);
      }
 
      // POST
      // Avec deux valeurs (username et password) dans le formulaire.
      HttpPost httpPostFile = new HttpPost("http://httpbin.org/post");
      httpPostFile.setEntity(new FileEntity(new File("/tmp/test"), ContentType.TEXT_PLAIN));
      try (CloseableHttpResponse response2 = httpclient.execute(httpPostFile)) {
        System.out.println(response2.getStatusLine());
        HttpEntity entity2 = response2.getEntity();
        System.out.println(entity2.getContentType());
        System.out.println(new BufferedReader(new InputStreamReader(entity2.getContent())).lines().parallel()
            .collect(Collectors.joining("\n")));
        EntityUtils.consume(entity2);
      }
    }
  }
}

Serveur

Il est possible d'utiliser un Servlet ou alors un HttpRequestHandler (ci-dessous).

Commencez par créer un nouveau Java Project, et installer la librairie HttpCore 4.4.5 (GA), Archive. Dans cet exemple, il sera nécessaire d'utiliser la librairie httpcore-4.4.5.jar.

Server.java
package org.llgc;
 
import java.io.IOException;
import java.util.concurrent.TimeUnit;
 
import org.apache.http.ExceptionLogger;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.config.SocketConfig;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.bootstrap.HttpServer;
import org.apache.http.impl.bootstrap.ServerBootstrap;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpProcessorBuilder;
import org.apache.http.protocol.HttpRequestHandler;
import org.apache.http.protocol.RequestConnControl;
import org.apache.http.protocol.RequestContent;
import org.apache.http.protocol.RequestExpectContinue;
import org.apache.http.protocol.RequestTargetHost;
import org.apache.http.protocol.RequestUserAgent;
 
public class Main {
  private static class MyHttpRequestHandler implements HttpRequestHandler {
    @Override
    public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
      response.setStatusCode(HttpStatus.SC_OK);
      response.setEntity(new StringEntity("some important message", ContentType.TEXT_PLAIN));
    }
  }
 
  public static void main(String[] args) throws IOException, InterruptedException {
    HttpRequestHandler requestHandler = new MyHttpRequestHandler();
    HttpProcessor httpProcessor = HttpProcessorBuilder.create()
        // Required protocol interceptors
        .add(new RequestContent()).add(new RequestTargetHost())
        // Recommended protocol interceptors
        .add(new RequestConnControl()).add(new RequestUserAgent("MyAgent-HTTP/1.1"))
        // Optional protocol interceptors
        .add(new RequestExpectContinue(true)).build();
    SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(15000).setTcpNoDelay(true).build();
    final HttpServer server = ServerBootstrap.bootstrap().setListenerPort(8080).setHttpProcessor(httpProcessor)
        .setSocketConfig(socketConfig).setExceptionLogger(new StdErrorExceptionLogger())
        .registerHandler("*", requestHandler).create();
    server.start();
    server.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
    Runtime.getRuntime().addShutdownHook(new Thread() {
      @Override
      public void run() {
        server.shutdown(5, TimeUnit.SECONDS);
      }
    });
  }
 
  static class StdErrorExceptionLogger implements ExceptionLogger {
    @Override
    public void log(final Exception ex) {
      ex.printStackTrace();
    }
 
  }
}

UDP

Si le but est de faire passer du texte, on pourra prendre un Charset de UTF-8. Par contre, pour faire transiter de la donnée brute, il faut laisser la valeur par défaut (windows-1252 probablement).

Serveur

serveurUDP.java
package org.llgc;
 
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.Charset;
 
public class ServeurUDP
{
  private static final int PORT = 9632;
 
  public static void main (String[] args)
  {
    try (DatagramSocket socket = new DatagramSocket (PORT))
    {
      while (true)
      {
        byte[] buffer = new byte[1024];
        DatagramPacket paquet = new DatagramPacket (buffer, buffer.length);
        socket.receive (paquet);
        String data = new String (paquet.getData (), 0, paquet.getLength (), Charset.forName ("UTF-8"));
        System.out.println (paquet.getAddress () + " \"" + data + "\"");
 
        String messageRenvoye = "Bonjour"
            + new String (paquet.getData (), 0, paquet.getLength (), Charset.forName ("UTF-8"));
        DatagramPacket envoie = new DatagramPacket (messageRenvoye.getBytes (Charset.forName ("UTF-8")),
            messageRenvoye.getBytes (Charset.forName ("UTF-8")).length, paquet.getAddress (), paquet.getPort ());
        socket.send (envoie);
        if (data.compareTo ("GoodBye") == 0)
        {
          break;
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace ();
      return;
    }
  }
}

Client

clientUDP.java
package org.llgc;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
 
public class ClientUDP
{
  private static final int PORT = 9632;
  private static final String SERVER_NAME = "localhost";
 
  public static void main (final String[] args)
  {
    InetAddress adr = null;
    try
    {
      adr = InetAddress.getByName (SERVER_NAME);
    }
    catch (UnknownHostException e)
    {
      e.printStackTrace ();
      return;
    }
 
    try (BufferedReader clavier = new BufferedReader (new InputStreamReader (System.in, Charset.forName ("UTF-8"))))
    {
      while (true)
      {
        String message = clavier.readLine ();
        if (message == null)
        {
          break;
        }
 
        try (DatagramSocket socket = new DatagramSocket ())
        {
          DatagramPacket paquet = new DatagramPacket (message.getBytes (Charset.forName ("UTF-8")),
              // message.length () n'est pas bon dans le cas de l'unicode.
              message.getBytes (Charset.forName ("UTF-8")).length, adr, PORT);
          socket.send (paquet);
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace ();
      return;
    }
  }
}
lang/java/net/client_serveur.txt · Dernière modification : 2019/01/17 14:33 de root