There are at least two separate questions. One of them is how to structure the matlab code that talks about such a protocol. Another is how to represent possibly complex data in this wired protocol that you have.
Regarding the organization of Matlab code, you can use the class to organize the message in a more structured way and use typecast to convert numbers to bytes. Maybe something like this. This assumes that your client and server have the same native representation of primitive types and ignore the byte order on the network (htonl / ntohl).
classdef learnvst_message %//LEARNVST_MESSAGE Message for learnvst 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, 1, '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, 0, numel(m.headerBytes)); d_output.write(m.messageBytes, 0, 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
More readable, I think, and slightly less code smell. As a caller, you can work with data in a more structured form and encapsulate the conversion to bytes of the wire protocol inside the class sorting method. This "convertPayload" is what "stitches together a common block of memory together from many different data types." In Matlab, the uint8 array is a way to add representations of different data types together in a limited block of memory. This is basically a wrapper around unsigned char [] with automatic redistribution. And typecast(...,'uint8') is a kind of equivalent that reinterprets casts to char * in C / C ++. See Help for both of them.
But that raises more questions. How does the server know how long each component of the payload is, what is their shape, multidimensional, and what are their respective types? Or what if they are complex data types - could they nest? You may need to embed small headers inside each payload element. The code above assumes that the 4-byte header of the payload type fully describes the contents of the payload.
It looks like what you are looking for could be a kind of self-descriptive format for heterogeneous arrays. There are existing formats for this, including NetCDF, HDF5 and Matlab's own MAT files. Matlab has built-in support for them, or you can use third-party Java libraries for them.
As for speed, you have to pay every time you transfer data across the Matlab / Java border. Large primitive arrays are relatively cheap to convert, so you probably want to pack most of the message in a byte array in Matlab before passing it to Java, instead of making many separate write () calls. In practice, this will depend on how large and complex your data is. See Is MATLAB OOP Slower or Am I Something Wrong? for a rough idea of ββthe cost of some Matlab operations, including Java calls. (Full disclosure: this is self-locking.)