Socket communication between server applications and MATLAB clients using java

I have a written C server application that I hope can be controlled from MATLAB So far, I have used the mex function for socket communication, but I want to abandon the mex function and use inline Java directly in the m file This will be a simpler solution

My C-based stand-alone application needs to display messages containing the following data in the following order

This part of the agreement is fixed and cannot be changed:

> uint32 magic_ Number – this is a magic number that must be reached (445566). The beginning of the message or the rest of the message will be ignored. > uint32 num_ Bytes – this is the number of bytes used for the rest of the message block (excluding the first 8 bytes)

This part of the agreement was designed by me and can be changed:

>Next, a header composed of four uint8 values (such as IPv4 address) signals the application what the following data represents (if any) > after that, the remaining bytes can represent many different things Most commonly, this will be a string (key value) followed by a long string of floating point values (audio data) However, there may be only one string, or they may be just an array of floating point values The uint8 value lets the server know what will happen here

As you can see, I'm currently compressing everything into a uint 8 array (huge kludge) This is because the Java "write" function requires a byte array, and the MATLAB uint8 array is a compatible data type, as I found when using the following table on the MathWorks website

I'm not a java programmer, but I've managed to get a very simple communication code this afternoon Can anyone help me do better?

import java.net.socket
import java.io.*

mySocket = Socket('localhost',12345);
output_stream   = mySocket.getOutputStream;
d_output_stream = DataOutputStream(output_stream);


data = zeros(12,1,'uint8');

%Magic key: use this combination of uint8s to make
% a uint32 value of = 445566 -> massive code-smell
data(1) = 126;
data(2) = 204;
data(3) = 6;

%size of message block:
%total number of bytes in following message including header
%This is another uint32 i.e. (data(5:8))

data(5) = 4;

%header B: a group of 4 uint8s
data(9) = 1;
data(10) = 2;
data(11) = 3;
data(12) = 4;

%Main block of floats
%????


d_output_stream.write(data,numel(data));


pause(0.2);
mySocket.close;

I've tried to send a Java object consisting of different parts of the data I want to send, but I'm not sure how they will eventually be sorted in memory In C / C + +, it is easy to attach different data types to consecutive memory blocks and send it Is there a simple way for me to do this in Java? I finally hope to communicate in both directions, but now I can wait Thank you for reading

Solution

There are at least two different problems here One is how to build matlab code for protocols like this The other is how he represents possible complex data in this wired protocol

In terms of organizing matlab code, you can use classes to organize messages in a more structured way and use type conversion to convert numbers to bytes Maybe such a thing This assumes that your client and server have the same native representation of the original type, ignoring the network byte order (htonl / ntohl)

classdef learnvst_message
    %//LEARNVST_MESSAGE Message for learnvst's example problem
    %
    % Examples:
    % msg = learnvst_message;
    % msg.payload = { 'Hello world',1:100 }
    % msg.payloadType = uint8([ 5 12 0 0 ]);  % guessing on this

    properties
        magicNumber = uint32(445566);
        payloadType = zeros(4,'uint8');  %// header B
        payload = {};
    end

    methods
        function out = convertPayload(obj)
        %//CONVERTPAYLOAD Converts payload to a single array of bytes
        byteChunks = cellfun(@convertPayloadElement,obj.payload,'UniformOutput',false);
        out = cat(2,byteChunks{:});
        end

        function out = marshall(obj)
        payloadBytes = convertPayload(obj);
        messageSize = uint32(4 + numel(payloadBytes)); %// ex first 8 bytes
        out.headerBytes = [
            typecast(obj.magicNumber,'uint8') ...
            obj.payloadType ...
            typecast(messageSize,'uint8')];
        out.payloadBytes = payloadBytes;
        end

        function sendTo(obj,host,port)
        m = marshall(obj);
        mySocket = Socket(host,port);
        d_output = mySocket.getOutputStream();
        d_output.write(m.headerBytes,numel(m.headerBytes));
        d_output.write(m.messageBytes,numel(m.messageBytes));
        mySocket.close();
        end

    end
end

function out = convertPayloadElement(x)
if isnumeric(x)
    out = typecast(x,'uint8');
elseif ischar(x)
    % Assumes receiver likes 16-bit Unicode chars
    out = typecast(uint16(x),'uint8');
else
    % ... fill in other types here ...
    % or define a payload_element class that marshalls itself and call
    % it polymorphically
    error('Unsupported payload element type: %s',class(x));
end
end

I think it's more readable and the code tastes less As a caller, you can process the data in a more structured form and encapsulate the transformation into wired protocol bytes in the marshalling method of the class "Convertpayload" is "splicing common memory blocks composed of many different data types together" In MATLAB, uint8 array is a method to attach the representations of different data types together in consecutive memory blocks It is basically an unsigned char [] wrapper with automatic redistribution function And type conversion (...,'uint8 ') is equivalent to reinterpretation of char * in C / C + + See the help for both

But this will bring more problems How does the server know how long each component of the payload is, what their shape is when multidimensional, and what their respective types are? Or if they are complex data types – can they be nested? You may need to embed subheadings in each valid content element The above code assumes that the 4 - byte payload type header fully describes the payload content

It sounds like what you are looking for may be a self describing format of data based on heterogeneous arrays Existing formats, including NetCDF, HDF5 and Matlab's own mat files MATLAB has built-in support for them, or you can introduce third-party Java libraries for them

In terms of speed – you have to pay every time you transfer data at the MATLAB / Java boundary The conversion cost of large raw arrays is relatively low, so you may want to package most messages in byte arrays in MATLAB instead of making a large number of separate write () calls before passing them to Java In fact, it depends on the size and complexity of your data For an overview of the costs of some matlab operations, including Java calls, see is matlab OOP slow or am I doing something wrong (full disclosure: This is a self plug-in.)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>