I often see people asking about network communications on the MATLAB Newsgroup. Often this is for the communication between instances of MATLAB.
Using the ability to call Java directly from within MATLAB, I'm going to provide a short example of a client/server written solely in MATLAB and usable from Release 14 onwards (possibly even earlier).
I'm working on a little TCP/IP comms library at the moment using these techniques. It will provide a nice layer of abstraction and allow you to use Sockets as you would in other programming languages (as well as one can in a single thread). Keep an eye out for it on the File Exchange.
Interpreted Java?
Amazingly we can execute Java code, even from within the Command Window without the need to compile. For example, the traditional example:
>> import java.lang.*
>> System.out.println('Hello World')Hello World
To perform socket communications, we utilise the Java Socket and Input/OutputStream classes to pass data around viaTCP/IP sockets.
On the server side we use (unsurprisingly) a ServerSocket, which once a client has been accepted, provides a Socketaround which we wrap a DataOutputStream to which we can write data.
On the client side we use a Socket to connect to the specified host and port which provides us an InputStream which we wrap in a DataInputStream to read data from.
The code for the example server and client is outlined below.
client.m
% CLIENT connect to a server and read a message
%% Usage - message = client(host, port, number_of_retries)function message = client(host, port, number_of_retries)import java.net.Socketimport java.io.*if (nargin <>number_of_retries = 20; % set to -1 for infiniteendretry = 0;input_socket = [];message = [];while trueretry = retry + 1;if ((number_of_retries > 0) && (retry > number_of_retries))fprintf(1, 'Too many retries\n');break;endtryfprintf(1, 'Retry %d connecting to %s:%d\n', ...retry, host, port);% throws if unable to connectinput_socket = Socket(host, port);% get a buffered data input stream from the socketinput_stream = input_socket.getInputStream;d_input_stream = DataInputStream(input_stream);fprintf(1, 'Connected to server\n');% read data from the socket - wait a short time firstpause(0.5);bytes_available = input_stream.available;fprintf(1, 'Reading %d bytes\n', bytes_available);message = zeros(1, bytes_available, 'uint8');for i = 1:bytes_availablemessage(i) = d_input_stream.readByte;endmessage = char(message);% cleanupinput_socket.close;break;catchif ~isempty(input_socket)input_socket.close;end% pause before retryingpause(1);endendend
server.m
% SERVER Write a message over the specified port
%% Usage - server(message, output_port, number_of_retries)function server(message, output_port, number_of_retries)import java.net.ServerSocketimport java.io.*if (nargin <>number_of_retries = 20; % set to -1 for infiniteendretry = 0;server_socket = [];output_socket = [];while trueretry = retry + 1;tryif ((number_of_retries > 0) && (retry > number_of_retries))fprintf(1, 'Too many retries\n');break;endfprintf(1, ['Try %d waiting for client to connect to this ' ...'host on port : %d\n'], retry, output_port);% wait for 1 second for client to connect server socketserver_socket = ServerSocket(output_port);server_socket.setSoTimeout(1000);output_socket = server_socket.accept;fprintf(1, 'Client connected\n');output_stream = output_socket.getOutputStream;d_output_stream = DataOutputStream(output_stream);% output the data over the DataOutputStream% Convert to stream of bytesfprintf(1, 'Writing %d bytes\n', length(message))d_output_stream.writeBytes(char(message));d_output_stream.flush;% clean upserver_socket.close;output_socket.close;break;catchif ~isempty(server_socket)server_socket.closeendif ~isempty(output_socket)output_socket.closeend% pause before retryingpause(1);endendend
Opening up two instances of Matlab:
% Instance 1
>> message = char(mod(1:1000, 255)+1);>> server(message, 3000, 10)Try 1 waiting for client to connect to this host on port : 3000Try 2 waiting for client to connect to this host on port : 3000Try 3 waiting for client to connect to this host on port : 3000Try 4 waiting for client to connect to this host on port : 3000Client connectedWriting 1000 bytes% Instance 2 (simultaneously)% NOTE: If the 'server' was runnning on a non local machine, substitute its IP address% or host name here:% data = client('10.61.1.200', 2666); % To connect to server at IP 10.61.1.200:2666>> data = client('localhost', 3000)Retry 1 connecting to localhost:3000Retry 2 connecting to localhost:3000Connected to serverReading 1000 bytesdata =!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
This code can be expanded to read/write arbitrary data types, and SHOULD be expanded to properly deal with errors (ie not getting all of the buffer on receive end), but it serves as a simple example of how to get communication between MATLAB and other applications / instances of MATLAB.
0 comments:
Post a Comment