web-dev-qa-db-fra.com

Java application client / serveur avec sockets?

J'écris un Java package qui sera appelé par un autre langage (matlab). Si mon processus matlab se termine, je veux que le processus Java continue de fonctionner) . Chaque fois que matlab redémarre, il devrait pouvoir communiquer avec le processus en cours. Je pense donc que j'ai besoin que l'application Java communique via des sockets dans un modèle client/serveur. J'envisage d'avoir un ensemble simple de fonctions:

  • startServer (hôte, port)
  • runCommand (serveur, commande ...)
  • stopServer (hôte, port)

Je n'ai jamais rien fait de tel auparavant. Est-ce que j'y pense de la bonne manière, ou y a-t-il un moyen plus facile de créer une application qui peut s'exécuter indépendamment du processus de son parent? Quelle est la meilleure façon moderne de le faire (par exemple, existe-t-il de bons packages Apache)? Quelqu'un peut-il fournir une démonstration simple ou me diriger vers un didacticiel sur la communication avec un processus via des sockets?

[Edit] Pour des éclaircissements, matlab est capable d'instancier un Java et d'exécuter Java code en lui-même. Ainsi, startServer () dans matlab exécuterait Java code qui vérifiera si un processus Java est déjà en cours d'exécution sur ce port et sinon, démarrez le processus serveur).

Je ne suis pas du tout lié à l'utilisation de sockets (au cas où ce ne serait pas évident, je suis principalement un développeur de matlab), donc s'il y a quelque chose de plus facile, je suis tout à fait d'accord. J'ai juste besoin de pouvoir exécuter les choses indépendamment de matlab, mais que matlab contrôle ces processus (via Java).

20
griffin

Le serveur écoute une connexion. Lorsqu'une connexion est établie par un client. Le client peut envoyer des données. Dans l'exemple actuel, le client envoie le message "Salut mon serveur". Pour mettre fin à la connexion, le client envoie le message "bye". Ensuite, le serveur envoie également le message "bye". Enfin, la connexion est terminée et le serveur attend une autre connexion. Les deux programmes doivent s'exécuter sur la même machine. cependant, si vous souhaitez les exécuter sur deux machines différentes, vous pouvez simplement changer l'adresse "localhost" par l'adresse IP de la machine sur laquelle vous exécuterez le serveur.

Le serveur

import Java.io.*;
import Java.net.*;
public class Provider{
    ServerSocket providerSocket;
    Socket connection = null;
    ObjectOutputStream out;
    ObjectInputStream in;
    String message;
    Provider(){}
    void run()
    {
        try{
            //1. creating a server socket
            providerSocket = new ServerSocket(2004, 10);
            //2. Wait for connection
            System.out.println("Waiting for connection");
            connection = providerSocket.accept();
            System.out.println("Connection received from " + connection.getInetAddress().getHostName());
            //3. get Input and Output streams
            out = new ObjectOutputStream(connection.getOutputStream());
            out.flush();
            in = new ObjectInputStream(connection.getInputStream());
            sendMessage("Connection successful");
            //4. The two parts communicate via the input and output streams
            do{
                try{
                    message = (String)in.readObject();
                    System.out.println("client>" + message);
                    if (message.equals("bye"))
                        sendMessage("bye");
                }
                catch(ClassNotFoundException classnot){
                    System.err.println("Data received in unknown format");
                }
            }while(!message.equals("bye"));
        }
        catch(IOException ioException){
            ioException.printStackTrace();
        }
        finally{
            //4: Closing connection
            try{
                in.close();
                out.close();
                providerSocket.close();
            }
            catch(IOException ioException){
                ioException.printStackTrace();
            }
        }
    }
    void sendMessage(String msg)
    {
        try{
            out.writeObject(msg);
            out.flush();
            System.out.println("server>" + msg);
        }
        catch(IOException ioException){
            ioException.printStackTrace();
        }
    }
    public static void main(String args[])
    {
        Provider server = new Provider();
        while(true){
            server.run();
        }
    }
}

Le client

import Java.io.*;
import Java.net.*;
public class Requester{
    Socket requestSocket;
    ObjectOutputStream out;
    ObjectInputStream in;
    String message;
    Requester(){}
    void run()
    {
        try{
            //1. creating a socket to connect to the server
            requestSocket = new Socket("localhost", 2004);
            System.out.println("Connected to localhost in port 2004");
            //2. get Input and Output streams
            out = new ObjectOutputStream(requestSocket.getOutputStream());
            out.flush();
            in = new ObjectInputStream(requestSocket.getInputStream());
            //3: Communicating with the server
            do{
                try{
                    message = (String)in.readObject();
                    System.out.println("server>" + message);
                    sendMessage("Hi my server");
                    message = "bye";
                    sendMessage(message);
                }
                catch(ClassNotFoundException classNot){
                    System.err.println("data received in unknown format");
                }
            }while(!message.equals("bye"));
        }
        catch(UnknownHostException unknownHost){
            System.err.println("You are trying to connect to an unknown Host!");
        }
        catch(IOException ioException){
            ioException.printStackTrace();
        }
        finally{
            //4: Closing connection
            try{
                in.close();
                out.close();
                requestSocket.close();
            }
            catch(IOException ioException){
                ioException.printStackTrace();
            }
        }
    }
    void sendMessage(String msg)
    {
        try{
            out.writeObject(msg);
            out.flush();
            System.out.println("client>" + msg);
        }
        catch(IOException ioException){
            ioException.printStackTrace();
        }
    }
    public static void main(String args[])
    {
        Requester client = new Requester();
        client.run();
    }
}
27
Sajad Bahmani

Il semble que vous ayez besoin du processus serveur Java pour être indépendant du processus Matlab. Ainsi, lorsque le processus Matlab démarre/s'arrête, le serveur Java continue). Java serveur va s'asseoir et attendre les connexions entrantes, et gérer plusieurs connexions, déconnexions, etc.

Voici un tutoriel pour écrire un Java (notez que cela fait partie d'un tutoriel plus large sur Java communication socket/client socket serveur) .

Un défi auquel vous serez confronté (et je ne peux pas vous aider ici en ignorant Matlab) consiste à créer ou à utiliser un moyen indépendant de la plate-forme pour créer le message réel, que ce soit en utilisant une représentation binaire, XML (on dirait que Matlab a certaines fonctionnalités XML ) ou autre.

2
Brian Agnew

Si vous décidez d'utiliser un protocole personnalisé au niveau du socket, je peux vous suggérer d'utiliser JBoss Netty à la fin Java:

En d'autres termes, Netty est une infrastructure de serveur client NIO qui permet un développement rapide et facile des applications réseau telles que les serveurs de protocole et les clients. Il simplifie et rationalise considérablement la programmation réseau telle que TCP et le serveur de socket UDP.

2
skaffman

Si, comme vous le dites, matlab peut exécuter Java code de lui-même, alors il ne devrait y avoir aucune raison de ne pas utiliser RMI pour communiquer entre matlab et Java. RMI est largement plus facile que la programmation par socket brut.

2
skaffman

La partie la plus facile est le tutoriel: Tutoriel Sockets de Sun m'a appris tout ce que je devais savoir sur la programmation des sockets, et j'espère le faire pour vous aussi.

Je pense que vous devez clarifier votre réflexion sur les commandes que vous souhaitez prendre en charge, en particulier la première et la troisième:

  • Si le processus Java n'est pas en cours d'exécution, qui va répondre à votre commande startServer? Et s'il est en cours d'exécution, qui en a besoin? :)

  • Vous pouvez certainement implémenter une commande stopServer. Mais ce serait un peu comme si votre ordinateur tirait son propre cordon d'alimentation du mur. Nous revenons à la question précédente: Si le serveur est arrêté, qui entendra la commande start?

Si je comprends bien, la seule opération à distance dont vous avez besoin est celle du milieu.

Cependant ... la programmation de socket n'est que modérément amusante. Vous pouvez envisager de consulter le tutoriel RMI pour une alternative.

1
Carl Smotricz

Toute raison pour laquelle vous ne pouvez pas simplement implémenter votre Java en tant que collection de servlets dans tomcat? Tomcat est fourni avec tous les outils pour démarrer automatiquement et maintenir le serveur en marche, vous pouvez implémenter SOAP ou services Web RESTful assez facilement qui vous aideront à dissocier votre code matlab de votre code Java.

1
Suppressingfire