Serveur de commandes TCP/IP Matlab sans aucune toolbox

La fonction suivante (que vous devez placer dans tcp_command_server.m) vous permet d’exécuter des commandes MATLAB à distance via TCP/IP sans nécessiter l’Instrument Control Toolbox ou toute autre toolbox (la fonction tcpip est uniquement disponible dans l’Instrument Control Toolbox, mais l’API Java sous-jacente est universellement disponible)

Note : S’arrêter simplement avec Ctrl-C n’arrêtera pas immédiatement le serveur. Après avoir appuyé sur Ctrl-C, connectez-vous avec un client pour sortir de la boucle.

Serveur MATLAB

tcp_command_server.m
function tcp_command_server()
  % Définir le port
  port = 13972;

  try
    % Créer un ServerSocket Java
    import java.net.*;
    import java.io.*;
    server_socket = ServerSocket(port);
    server_socket.setSoTimeout(0); % Pas de timeout

    fprintf('Serveur démarré. En attente de connexions sur le port %d...\n', port);
    fprintf('Appuyez sur Ctrl+C pour arrêter le serveur.\n');

    % Attendre les connexions client
    while true
      try
        % Bloque jusqu'à ce qu'une connexion soit établie
        client = server_socket.accept();
        fprintf('Client connecté: %s\n', client.getInetAddress().getHostAddress());

        % Configurer les flux d'entrée et de sortie
        input_stream = BufferedReader(InputStreamReader(client.getInputStream()));
        output_stream = PrintWriter(client.getOutputStream(), true);

        % Lire et exécuter les commandes du client
        while client.isConnected()
          % Lire la commande (blocant)
          command = input_stream.readLine();

          % Si le client a fermé la connexion
          if isempty(command)
            break;
          end

          fprintf('Commande reçue: %s\n', char(command));

          try
            % Exécuter la commande
            result = evalc(char(command));
            % Renvoyer le résultat
            output_stream.println(['Result: ', result]);
          catch e
            % Gérer les erreurs
            error_msg = ['Error: ', e.message];
            fprintf('%s\n', error_msg);
            output_stream.println(error_msg);
          end
        end

        % Fermer la connexion
        client.close();
        fprintf('Client déconnecté.\n');

      catch e
        if ~strcmp(e.identifier, 'MATLAB:Java:GenericException')
          fprintf('Erreur lors du traitement du client: %s\n', e.message);
        end
      end
    end

  catch e
    fprintf('Erreur serveur: %s\n', e.message);
  end

  % Fermer le socket serveur
  if exist('server_socket', 'var') && ~isempty(server_socket)
    server_socket.close();
  end

  fprintf('Serveur arrêté.\n');
end

Exemple de client

Ce client Python se connecte au serveur et envoie un ensemble de commandes :

matlab_tcp_client.py
#!/usr/bin/env python3
import socket
import time

def connect_to_matlab_server(host='localhost', port=13972):
    try:
        # Créer un socket
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # Se connecter au serveur
        print(f"Establishing connection to {host}:{port}...")
        client.connect((host, port))
        print("Connection established!")

        # Trois commandes MATLAB à envoyer
        commands = [
            "disp('Hello from Python client!')",
            "a = 5 + 10",
            "disp(['The result is: ', num2str(a)])"
        ]

        # Envoyer chaque commande et recevoir la réponse
        for cmd in commands:
            print(f"\nSending command: {cmd}")
            # Envoyer la commande (avec nouvelle ligne)
            client.sendall((cmd + '\n').encode())

            # Attendre brièvement et recevoir la réponse
            time.sleep(0.5)
            response = client.recv(4096).decode().strip()
            print(f"Response received: {response}")

        print("\nClosing connection...")

    except Exception as e:
        print(f"Error: {e}")
    finally:
        # Fermer le socket
        client.close()
        print("Connection closed.")

if __name__ == "__main__":
    connect_to_matlab_server()

Exemple de sortie

Sortie Python :

matlab_tcp_client_output.txt
Establishing connection to localhost:13973...
Connection established!

Sending command: disp('Hello from Python client!')
Response received: Result: Hello from Python client!

Sending command: a = 5 + 10
Response received: Result:
a =

    15

Sending command: disp(['The result is: ', num2str(a)])
Response received: Result: The result is: 15

Closing connection...
Connection closed.

Sortie MATLAB :

tcp_server_output.txt
Server started. Waiting for connections on port 13973...
Press Ctrl+C to stop the server.
Client connected: 127.0.0.1
Received command: disp('Hello from Python client!')
Received command: a = 5 + 10
Received command: disp(['The result is: ', num2str(a)])
Client disconnected.

Comment le démarrer en arrière-plan

Cette fonction peut être utilisée pour exécuter le serveur TCP en arrière-plan en utilisant un timer. Vous pouvez appeler cette fonction pour démarrer le serveur sans bloquer la fenêtre de commande MATLAB.

Notez que cela ne bloquera pas la fenêtre de commande mais Matlab est toujours intrinsèquement monothreadé, donc exécuter une simulation Simulink dans la même session MATLAB ne fonctionnera pas pendant que le serveur est en cours d’exécution.

start_tcp_server_background.m
% Démarrer le serveur TCP en arrière-plan en utilisant un timer
function start_tcp_server_background()
  % Créer un timer
  t = timer;
  t.StartDelay = 1;
  t.TimerFcn = @(~,~)tcp_command_server();
  t.StopFcn = @(~,~)disp('TCP server stopped.');
  t.ErrorFcn = @(~,~)disp('TCP server error occurred!');

  % Démarrer le timer
  start(t);
  disp('TCP server started in the background.');
  disp('Use "stop(timerfindall)" to stop all servers.');
end
example.txt

Consultez les articles similaires par catégorie : Matlab/Simulink