. About the Matlab server      package:R.matlab      R Documentation

. _A_b_o_u_t _t_h_e _M_a_t_l_a_b _s_e_r_v_e_r

_D_e_s_c_r_i_p_t_i_o_n:

     This section gives addition details on the Matlab server. At the
     end, the MatlabServer.m script and the InputStreamByteWrapper.java
     code is shown.

_S_t_a_r_t_i_n_g _t_h_e _M_a_t_l_a_b _s_e_r_v_e_r _o_n _W_i_n_d_o_w_s:

     Note that you "cannot prevent Matlab from creating a window when
     starting on Windows systems, but you can force the window to be
     hidden, by using " the option -minimize. See <URL:
     http://www.mathworks.com/support/solutions/data/1-16B8X.html> for
     more information.

_M_a_t_l_a_b_S_e_r_v_e_r._m _s_c_r_i_p_t:



     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     %%%%%%%%%
     % MatlabServer
     %
     % This scripts starts a minimalistic Matlab "server".
     %
     % Troubleshooting: If not working out of the box, add this will to
     the
     % Matlab path. Make sure InputStreamByteWrapper.class is in the
     same
     % directory as this file!
     %
     % Requirements:
     % This requires Matlab with Java support, i.e. Matlab v6 or
     higher.
     %
     % Author: Henrik Bengtsson, 2002-2005
     %
     % References:
     % [1] http://www.mathworks.com/access/helpdesk/help/techdoc/
     %                                    
     matlab_external/ch_jav34.shtml#49439
     % [2] http://staff.science.uva.nl/~horus/dox/horus2.0/user/
     %                                                 
     html/n_installUnix.html
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     %%%%%%%%%

     %  addpath R/R_LIBS/linux/library/R.matlab/misc/

     % Detect major Matlab version
     isVersion7 = eval('length(regexp(version, ''^7'')) ~= 0', '0');
     if (~isVersion7)
       disp('Matlab v6.x detected.');
       % Default save option
       saveOption = '';
       % In Matlab v6 only the static Java CLASSPATH is supported. It
     is
       % specified by a 'classpath.txt' file. The default one can be
     found
       % by which('classpath.txt'). If a 'classpath.txt' exists in the
       % current(!) directory (that Matlab is started from), it
     *replaces*
       % the global one. Thus, it is not possible to add additional
     paths;
       % the global ones has to be copied to the local 'classpath.txt'
     file.
       %
       % To do the above automatically from R, does not seem to be an
     option.
     else
       disp('Matlab v7.x or higher detected.');
       % Matlab v7 saves compressed files, which is not recognized by
       % R.matlab's readMat(); force saving in old format.
       saveOption = '-V6';
       disp('Saving with option -V6.');

       % In Matlab v7 both static and dynamic Java CLASSPATH:s exist.
       % Using dynamic ones, it is possible to add the file
       % InputStreamByteWrapper.class to CLASSPATH, given it is
       % in the same directory as this script.
       javaaddpath({fileparts(which('MatlabServer'))});
       disp('Added InputStreamByteWrapper to dynamic Java CLASSPATH.');
     end

     % Importing Java classes
     import java.io.*;
     import java.net.*;

     % If a server object exists from a previous run, close it.
     if (exist('server'))
       close(server);
       clear server;
     end

     % If an input stream exists from a previous run, close it.
     if (exist('is'))
       close(is);
       clear is;
     end

     % If an output stream exists from a previous run, close it.
     if (exist('os'))
       close(os);
       clear os;
     end

     fprintf(1, '----------------------\n');
     fprintf(1, 'Matlab server started!\n');
     fprintf(1, '----------------------\n');

     % Try to open a server socket on port 9999
     % Note that we can't choose a port less than 1023 if we are not
     % privileged users (root)
     port = 9999;

     server = ServerSocket(port);
     fprintf(1, 'Server socket created.\n');


     % Create a socket object from the ServerSocket to listen and
     accept
     % connections.
     % Open input and output streams

     % Wait for the client to connect
     clientSocket = accept(server);

     fprintf(1, 'Connected to client.\n');

     % ...client connected.
     is = DataInputStream(getInputStream(clientSocket));
     %is = BufferedReader(InputStreamReader(is0));
     os = DataOutputStream(getOutputStream(clientSocket));

     % Commands
     commands = {'eval', 'send', 'receive', 'send-remote',
     'receive-remote', 'echo'};

     % As long as we receive data, echo that data back to the client.
     state = 0;
     while (state >= 0),
       if (state == 0)
         cmd = readByte(is);
         fprintf(1, 'Received cmd: %d\n', cmd);
         if (cmd < -1 | cmd > length(commands))
           fprintf(1, 'Unknown command code: %d\n', cmd);
         else
           state = cmd;
         end

       %-------------------
       % 'eval'
       %-------------------
       elseif (state == strmatch('eval', commands, 'exact'))
         bfr = char(readUTF(is));
         fprintf(1, '"eval" string: "%s"\n', bfr);
         try
           eval(bfr);,
           writeByte(os, 0);
           fprintf(1, 'Sent byte: %d\n', 0);
           flush(os);
         catch,
           fprintf(1, 'EvaluationException: %s\n', lasterr);
           writeByte(os, -1);
           fprintf(1, 'Sent byte: %d\n', -1);
           writeUTF(os, lasterr);
           fprintf(1, 'Sent UTF: %s\n', lasterr);
           flush(os);
         end
         flush(os);
         state = 0;

       %-------------------
       % 'send'
       %-------------------
       elseif (state == strmatch('send', commands, 'exact'))
         tmpname = sprintf('%s.mat', tempname);
         expr = sprintf('save %s %s', tmpname, saveOption);
         ok = 1;
         for k=1:length(variables),
           variable = variables{k};
           if (exist(variable) ~= 1)
             lasterr = sprintf('Variable ''%s'' not found.', variable);
             ok = 0;
             break;
           end;
           expr = sprintf('%s %s', expr, variable);
         end;
         if (~ok)
           writeInt(os, -1);
           writeUTF(os, lasterr);
         else
           disp(expr);
           eval(expr);
           writeUTF(os, tmpname);
         end

         answer = readByte(is);
         fprintf('answer=%d\n', answer);

         state = 0;

       %-------------------
       % 'send-remote'
       %-------------------
       elseif (state == strmatch('send-remote', commands, 'exact'))
         tmpname = sprintf('%s.mat', tempname);
         expr = sprintf('save %s %s', tmpname, saveOption);
         ok = 1;
         for k=1:length(variables),
           variable = variables{k};
           if (exist(variable) ~= 1)
             lasterr = sprintf('Variable ''%s'' not found.', variable);
             ok = 0;
             break;
           end;
           expr = sprintf('%s %s', expr, variable);
         end;
         if (~ok)
           writeInt(os, -1);
           writeUTF(os, lasterr);
         else
           disp(expr);
           eval(expr);
           file = File(tmpname);
           maxLength = length(file);
           clear file;
           writeInt(os, maxLength);
           fprintf(1, 'Send int: %d (maxLength)\n', maxLength);
           fid = fopen(tmpname, 'r');
           count = 1;
           while (count ~= 0)
             [bfr, count] = fread(fid, 65536, 'int8');
             if (count > 0)
               write(os, bfr);
     %          fprintf(1, 'Wrote %d byte(s).\n', length(bfr));
             end;
           end;
           fclose(fid);
     %      fprintf(1, 'Wrote!\n');
           fprintf(1, 'Send buffer: %d bytes.\n', maxLength);
           delete(tmpname);
           clear bfr, count, maxLength, fid, tmpname;
         end
         flush(os);

         answer = readByte(is);
         fprintf('answer=%d\n', answer);

         state = 0;

       %-------------------
       % 'receive-remote'
       %-------------------
       elseif (state == strmatch('receive-remote', commands, 'exact'))
         len = readInt(is);
         fprintf(1, 'Will read MAT file structure of length: %d
     bytes.\n', len);

         reader = InputStreamByteWrapper(4096);
         bfr = [];
         count = 1;
         while (len > 0 & count > 0)
           count = reader.read(is, min(4096, len));
           if (count > 0)
             bfr = [bfr; reader.bfr(1:count)];
             len = len - count;
           end;
         end;

         clear reader count len;

         tmpfile = sprintf('%s.mat', tempname);
     %    tmpfile = 'tmp2.mat';
     %    disp(bfr');
     %    disp(tmpfile);
         fh = fopen(tmpfile, 'wb');
         fwrite(fh, bfr, 'int8');
         fclose(fh);

         clear fh, bfr;

         load(tmpfile);

         delete(tmpfile);
         clear tmpfile;
         writeByte(os, 0);

         state = 0;

       %-------------------
       % 'receive'
       %-------------------
       elseif (state == strmatch('receive', commands, 'exact'))
         filename = char(readUTF(is));
         fprintf(1, 'Will read MAT file: "%s"\n', filename);
         load(filename);
         clear filename;
         writeByte(os, 0);
         state = 0;
       end
     end

     fprintf(1, '-----------------------\n');
     fprintf(1, 'Matlab server shutdown!\n');
     fprintf(1, '-----------------------\n');
     writeByte(os, 0);
     close(os);
     close(is);
     close(server);


     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     %%%%%%%%%
     % HISTORY:
     % 2005-03-08
     % o BUG FIX: substring() is not recognized by Matlab v7. Using
     regexp()
     %   which works in Matlab 6.5 and 7. Workaround eval('try',
     'catch').
     %   Thanks Patrick Drechsler, University of Wuerzburg for the bug
     report.
     % 2005-02-24
     % o Now the dynamic Java classpath is set for Matlab v7 or higher.
     This
     %   will simplify life for Matlab v7 users.
     % 2005-02-22
     % o Added javaaddpath() to include InputStreamByteWrapper.class.
     %   Thanks Yichun Wei forfeedback and great suggestions.
     % 2005-02-11
     % o If Matlab v7 or higher is detected, all MAT structures are
     saved with
     %   option '-V6' so readMat() in R.matlab can read them.
     % 2002-09-02 [or maybe a little bit earlier]
     % o Created.
     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     %%%%%%%%%

      __

_I_n_p_u_t_S_t_r_e_a_m_B_y_t_e_W_r_a_p_p_e_r.(_c_l_a_s_s|_j_a_v_a) _s_c_r_i_p_t:

     The Java class InputStreamByteWrapper is needed in order for
     Matlab to _receive_ _data_ via a data stream. R sends data via a
     data stream if, and only if, the connection was setup for "remote"
     communication, that is, with argument 'remote=TRUE').



     import java.io.*;

     /*****************************************************************
     ****
     % Compile from within Matlab with:
     % !javac InputStreamByteWrapper.java

     % Matlab example that reads a file using Java code and writes it
     % back to a temporary file using Matlab code. Finally the contents
     % of the new file is displayed.

     reader = InputStreamByteWrapper;  % Default buffer size is 4096
     bytes.

     in = java.io.FileInputStream('InputStreamByteWrapper.java');

     bfr = [];
     len = 1;
     while (len > 0)
       len = reader.read(in, 16);  % Read 16 bytes at the time
     (offset=0).
       if (len > 0)
         bfr = [bfr; reader.bfr(1:len)];  % Add bytes to my Matlab
     buffer.
       end
     end

     close(in);
     clear in, reader;

     disp(bfr');

     tmpfile = tempname;
     fh = fopen(tmpfile, 'wb');
     fwrite(fh, bfr, 'char');
     fclose(fh);

     type(tmpfile);
     ******************************************************************
     ***/
     public class InputStreamByteWrapper {
       public static byte[] bfr = null;

       public InputStreamByteWrapper(int capasity) {
         bfr = new byte[capasity];
       }

       public InputStreamByteWrapper() {
         this(4096);
       }

       public int read(InputStream in, int offset, int length) throws
     IOException {
         return in.read(bfr, offset, length);
       }

       public int read(InputStream in, int length) throws IOException {
         return read(in, 0, length);
       }

       public int read(InputStream in) throws IOException {
         return in.read(bfr);
       }
     }

     /*****************************************************************
     ****
      HISTORY:
      2002-09-02 [or maybe a little bit earlier]
      o Created.
     ******************************************************************
     ***/


      __

