views:

1025

answers:

6

I'm writing a java package that will be called by another language (matlab). If my matlab process ends, I want the Java process to keep running. Whenever matlab starts again, it should be able to communicate with the existing running process. So I think I need to have the Java application communicating through sockets in a client/server model. I envision having a simple set of functions:

  • startServer(host, port)
  • runCommand(server, command...)
  • stopServer(host, port)

I have never done anything like this before. Am I thinking about it in the right way, or is there an easier way of building an application that can run independently of it's parent's process? What's the best modern way of doing this (e.g. are there any good Apache packages)? Can anyone provide a simple demo or point me to a tutorial on communicating with a process through sockets?

[Edit] For some clarification, matlab is able to instantiate a java object and run java code within itself. So the startServer() function in matlab would run java code that will check if a java process is already running on that port and if not, start the server process.

I'm not tied to using sockets by any means (in case it isn't obvious, I'm mostly a matlab developer), so if there's something easier, I'm all for it. I just need to be able to run things independently of matlab, but have matlab control those processes (through java).

+2  A: 

It sounds like you need the Java server process to be independent of the Matlab process. So when the Matlab process starts/stops, the Java server continues. The Java server will sit and wait for incoming connections, and handle multiple connections, disconnects etc.

Here's a tutorial for writing a Java socket server (note it's part of a larger tutorial on Java client/server socket communication).

One challenge you will face (and I can't help you here being Matlab-unaware) is creating or using a platform-independent means of creating the actual message, whether that's using a binary representation, XML (looks like Matlab has some XML functionality) or other.

Brian Agnew
That's what I was thinking. Do you know of any good examples for something like that?
griffin
I would run with that tutorial first of all, and see how intuitive (!) it is. Note additional comments above.
Brian Agnew
+3  A: 

The server listens for a connection. When a connection is established by a client. The client can send data. In the current example the client sends the message "Hi my server". To terminate the connection, the client sends the message "bye". Then the server sends the message "bye" too. Finally the connection is ended and the server waits for an other connection. The two programs should be runes in the same machine. however if you want to run them in two different machines, you may simply change the address "localhost" by the IP address of the machine where you will run the server.

The server

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();
     }
    }
}

The 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();
    }
}
SjB
ObjectI/OStream is handy, but I prefer to use PrintWriter and BufferedReader. I had already many problems with ObjectI/OStream.
Martijn Courteaux
+2  A: 

If you decide to go with a custom socket-level protocol, then I can suggest that you use JBoss Netty at the java end:

In other words, Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.

skaffman
+1  A: 

The easy part is the tutorial: Sun's Sockets Tutorial taught me everything I needed to know about sockets programming, and will hopefully do for you too.

I think you need to clarify your thinking about the commands you want to support, in particular the first and 3rd:

  • If the Java process isn't running, who's going to respond to your startServer command? And if it is running, who needs it? :)

  • You can certainly implement a stopServer command. But that would be kind of like having your computer pulling its own power cord out of the wall. We return to the previous question: If the server's stopped, who'll hear the start command?

As I understand it, the only remote operation you need is the middle one.

However... socket programming is only moderately fun. You may consider looking at the RMI tutorial for an alternative.

Carl Smotricz
+1  A: 

Any reason that you can't just implement your java server as a collection of servlets in tomcat? Tomcat comes with all the tools to autostart and keep the server running, you can implement SOAP service or RESTful web services pretty easily which will help to decouple your matlab code from your java code.

Suppressingfire
+1  A: 

If, as you say, matlab can run java code from within itself, then there should be no reason that you can't use RMI to communicate between matlab and java server. RMI is vastly easier than raw socket programming.

skaffman