Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于Java的服务器应用程序与Matlab客户端的Socket通信 我有一个C++的服务器应用程序,我希望能够从MATLAB中控制它。到目前为止,我已经在套接字通信中使用了mex函数,但是我想放弃mex函数,直接在m文件中使用内联Java。这将是一个更加精简的解决方案 基于C++的独立应用程序希望按照以下顺序来发送以下数据的消息…_Java_C++_Sockets_Matlab_Interprocess - Fatal编程技术网

基于Java的服务器应用程序与Matlab客户端的Socket通信 我有一个C++的服务器应用程序,我希望能够从MATLAB中控制它。到目前为止,我已经在套接字通信中使用了mex函数,但是我想放弃mex函数,直接在m文件中使用内联Java。这将是一个更加精简的解决方案 基于C++的独立应用程序希望按照以下顺序来发送以下数据的消息…

基于Java的服务器应用程序与Matlab客户端的Socket通信 我有一个C++的服务器应用程序,我希望能够从MATLAB中控制它。到目前为止,我已经在套接字通信中使用了mex函数,但是我想放弃mex函数,直接在m文件中使用内联Java。这将是一个更加精简的解决方案 基于C++的独立应用程序希望按照以下顺序来发送以下数据的消息…,java,c++,sockets,matlab,interprocess,Java,C++,Sockets,Matlab,Interprocess,协议的这一部分是固定的,不能更改: uint32魔术号码-这是一个魔术号码(445566),必须在 消息的开头或消息的其余部分将被忽略 uint32个字节- 这是消息块其余部分使用的字节数 (不包括首8个字节) 协议的这一部分由我设计,可以更改: 接下来是一个由4个uint8值(如ipv4地址)组成的头 向应用程序发送以下数据表示的内容的信号(如果有数据) 在此之后,剩余的字节可以表示许多不同的内容。 最常见的是一个字符串(键值),后跟一个长的浮点值数组(音频数据)。但是,可能只是一个字符

协议的这一部分是固定的,不能更改:

  • uint32魔术号码-这是一个魔术号码(445566),必须在 消息的开头或消息的其余部分将被忽略

  • uint32个字节- 这是消息块其余部分使用的字节数 (不包括首8个字节)

协议的这一部分由我设计,可以更改:

  • 接下来是一个由4个uint8值(如ipv4地址)组成的头 向应用程序发送以下数据表示的内容的信号(如果有数据)

  • 在此之后,剩余的字节可以表示许多不同的内容。 最常见的是一个字符串(键值),后跟一个长的浮点值数组(音频数据)。但是,可能只是一个字符串,也可能只是一个浮点值数组。4个uint8值让服务器知道这里需要什么

正如您所见,我目前正在将所有内容压缩到一个uint8数组中(一个巨大的kludge)。这是因为java“write”函数需要一个字节数组,而Matlab uint8数组是一种兼容的数据类型,正如我在Mathworks站点上使用下表时发现的那样

我不是一个Java程序员,但我今天下午已经设法获得了一个非常简单的通信代码并开始运行。有人能帮我把这个做得更好吗

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,0,numel(data));


pause(0.2);
mySocket.close;

我已经尝试过发送一个java对象,该对象由我想要发送的数据的不同部分组成,但我不确定它们最终如何在内存中排序。在C/C++中,在一个连续的内存块中附加不同的数据类型,然后发送它是非常容易的。在Java中有没有一种简单的方法可以做到这一点?我最终也希望实现双向通信,但这可以等到现在。感谢阅读。

这里至少有两个独立的问题。一个是如何构造讲这样一个协议的Matlab代码。另一个问题是如何在这个有线协议中表示可能复杂的数据

至于组织Matlab代码,您可以使用类以更结构化的方式组织消息,并使用
typecast
将数字转换为字节。也许是这样的。这假定客户端和服务器具有相同的基元类型本机表示形式,并忽略网络字节顺序(htonl/ntohl)

我认为,可读性更强,代码味道更少。作为调用者,您可以以更结构化的形式处理数据,它将转换封装到类的封送方法中的wire协议字节。“convertPayload”就是“将由许多不同数据类型组成的通用内存块缝合在一起”。在Matlab中,
uint8
数组是一种将不同数据类型的表示附加到连续内存块中的方法。它基本上是一个围绕
无符号字符[]
的包装器,具有自动重新分配功能。而
typecast(…,'uint8')
相当于在C/C++中对
char*
进行重新解释转换。请参阅他们两人的帮助

但这带来了更多的问题。服务器如何知道有效负载的每个组件有多长,如果是多维的,它们的形状是什么,它们各自的类型是什么?或者,如果它们是复杂的数据类型,它们会嵌套吗?您可能需要在每个有效负载元素中嵌入小标题。上面的代码假设4字节有效负载类型标头完全描述了有效负载内容

听起来您正在寻找的可能是一种用于异构阵列数据的自描述格式。现有的格式包括NetCDF、HDF5和Matlab自己的MAT文件。Matlab内置了对它们的支持,或者您可以为它们引入第三方Java库


就速度而言,每次通过Matlab/Java边界传递数据时,您都需要付费。大型基元数组的转换成本相对较低,因此在将其传递给Java之前,您可能希望将大部分消息打包到Matlab中的字节数组中,而不是进行大量单独的write()调用。实际上,这取决于您的数据有多大、多复杂。有关一些Matlab操作(包括Java调用)成本的大致信息,请参见。(完全公开:这是一个自插。)

当我在Matlab和Java之间发送数据时,我会发送具有必要属性的Java对象。也许你可以试试。你能缩小“许多不同的东西”的范围吗?它的组件总是一个原始数数组,还是其他可以直接表示为Matlab原始数组的东西?您需要从服务器获取数据吗?您确定“消息块大小”是一个字节吗?这将限制您发送256字节的消息。这是您自己设计的协议吗?我已经更新了问题,以涵盖这些问题中提出的一些要点。感谢您的关注。对于字符串(键值)后跟浮点数的情况,服务器如何知道字符串的长度以及浮点数的长度?4字节的报头编码长度,还是使用固定长度?你可能需要更多的副标题。看看MAT文件格式doco,看看Matlab本身是如何做到这一点的:哇!感谢您如此有见地的回复,感谢您抽出时间。现在这里的时间已经很晚了,所以我会在早上用它进行实验,用我当前的mex解决方案对它进行基准测试,然后发布结果。我
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, 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