Matlab:TCP连接读取数据大小警告错误
Matlab: TCP Connection Fread data Size Warning Error
我的 Matlab 代码中有一个 TCP 服务器,我的客户端在某些触发器上从另一个应用程序向 Matlab 发送一些数据(最多 4 个字节)。我收到了这些号码,但我也多次收到此警告消息:
警告:指定数量的数据未在超时期限内返回。 'tcpip' 无法读取所有请求的数据。有关可能原因的详细信息,请参阅 TCPIP 读取警告。
clc;
t = tcpip('0.0.0.0', 55000,'InputBufferSize', 1024,'NetworkRole','Server', 'TimeOut', 0.5);
fopen(t);
while(1)
data = fread(t, 4, 'char');
dataChar = char(data);
dataDouble = str2double(dataChar);
if (~isnan(dataDouble))
if (dataDouble == 0)
fclose(t); % closing the tcp connecting
error('0 value is received!') % to jump out of Matlab run mode
else
disp("Last Receieved double was: " + dataDouble)
end
end
end
我也尝试了 get(obj1,'BytesAvailable'),但它给了我错误。有谁知道如何绕过这个警告?
您正在尝试从 tcpip 对象读取数据,但没有可读取的数据(即缓冲区已经为空)。 Matlab 将等待一段时间以查看是否有任何内容出现,然后发出警告。
使用 tcpip obj 的正常方法是在某个事件上执行回调,并使用此回调从缓冲区读取数据。
有两种模式:当找到特定的终止符时触发缓冲区(例如换行符,如果阅读文本)或当接收到特定数量的字节时。
假设所有消息的字节长度为 4,则语法为:
t = tcpip('0.0.0.0', 55000,'InputBufferSize', 1024,'NetworkRole','Server', 'TimeOut', 0.5);
t.BytesAvailableFcnCount = 4; % n=4
t.BytesAvailableFcnMode = 'byte'; %Read after n bytes have been received
t.BytesAvailableFcn = @myTcpipCallback;
fopen(t);
每次接收到 4 个字节时都会调用回调。回调函数语法为:
function myTcpipCallback(obj,evt)
data=fread(obj,4,'char'); %Read 4 characters
% ... do something with data ... %
if bad_data_received==true
fclose(obj);
end
end
while 循环不是必需的,它已由 tcpip 对象在内部处理。回调函数的语法遵循 Matlab 标准 callbackFunction(obj,evt)
,其中 obj 是触发回调的事件来源的对象(这里是一个 tcpip
对象,但图形对象工作相同)和 evt
一个包含有关事件的数据的结构(例如 IP/port 来自消息的来源;对于将是键和修饰符的 KeyPress 事件)。
您写道,另一个应用程序上的客户端将发送最多 4 个字节。有一个固定的字节数确实更方便(这可以通过在客户端填充消息来实现)或者一些终结符应该标记结束。
使用终止符(例如假设每条消息以换行结束),语法为:
t.BytesAvailableFcnMode = 'terminator';
t.Terminator = char(10); % or newline or recent versions of Matlab
和回调
function myTcpipCallback(obj,evt)
data=[obj.UserData ; fread(obj,obj.BytesAvailable,'char')]; %Read all available characters
%Just in case, check that we have not received more than one message
term=[0;find(data==obj.Terminator)];
for ii=1:length(term)-1
msg=data(term(ii)+1:term(ii+1));
%Do something with msg%
end
obj.UserData=data(term(ii)+1:end);
end
如果客户端快速发送数据,当回调函数在队列中等待时,一些额外的数据可能已经被缓冲,因此在执行它时,可能有几条消息可用。代码应该考虑到这种可能性。不幸的是,触发回调时缓冲区中可用的字节数不在事件数据中。
最后,如果您打算接收具有复杂规则的任意长度的消息以确定它是否完整,另一种可能性是逐个读取字节并在某处拥有自己的缓冲区,例如在对象用户数据中。
t.BytesAvailableFcnCount = 1; % n=1
t.BytesAvailableFcnMode = 'byte'; %Read after n bytes have been received
和回调:
function myTcpipCallback(obj,evt)
% Bufferize
obj.UserData=[obj.UserData ; fread(obj,1,'char')]; %Read 1 byte
% Check if the message if known
msg = obj.UserData;
if isComplete(msg) %
obj.UserData=[]; % empty buffer
processMessage(msg); % do something with message
end
end
我的 Matlab 代码中有一个 TCP 服务器,我的客户端在某些触发器上从另一个应用程序向 Matlab 发送一些数据(最多 4 个字节)。我收到了这些号码,但我也多次收到此警告消息:
警告:指定数量的数据未在超时期限内返回。 'tcpip' 无法读取所有请求的数据。有关可能原因的详细信息,请参阅 TCPIP 读取警告。
clc;
t = tcpip('0.0.0.0', 55000,'InputBufferSize', 1024,'NetworkRole','Server', 'TimeOut', 0.5);
fopen(t);
while(1)
data = fread(t, 4, 'char');
dataChar = char(data);
dataDouble = str2double(dataChar);
if (~isnan(dataDouble))
if (dataDouble == 0)
fclose(t); % closing the tcp connecting
error('0 value is received!') % to jump out of Matlab run mode
else
disp("Last Receieved double was: " + dataDouble)
end
end
end
我也尝试了 get(obj1,'BytesAvailable'),但它给了我错误。有谁知道如何绕过这个警告?
您正在尝试从 tcpip 对象读取数据,但没有可读取的数据(即缓冲区已经为空)。 Matlab 将等待一段时间以查看是否有任何内容出现,然后发出警告。 使用 tcpip obj 的正常方法是在某个事件上执行回调,并使用此回调从缓冲区读取数据。
有两种模式:当找到特定的终止符时触发缓冲区(例如换行符,如果阅读文本)或当接收到特定数量的字节时。
假设所有消息的字节长度为 4,则语法为:
t = tcpip('0.0.0.0', 55000,'InputBufferSize', 1024,'NetworkRole','Server', 'TimeOut', 0.5);
t.BytesAvailableFcnCount = 4; % n=4
t.BytesAvailableFcnMode = 'byte'; %Read after n bytes have been received
t.BytesAvailableFcn = @myTcpipCallback;
fopen(t);
每次接收到 4 个字节时都会调用回调。回调函数语法为:
function myTcpipCallback(obj,evt)
data=fread(obj,4,'char'); %Read 4 characters
% ... do something with data ... %
if bad_data_received==true
fclose(obj);
end
end
while 循环不是必需的,它已由 tcpip 对象在内部处理。回调函数的语法遵循 Matlab 标准 callbackFunction(obj,evt)
,其中 obj 是触发回调的事件来源的对象(这里是一个 tcpip
对象,但图形对象工作相同)和 evt
一个包含有关事件的数据的结构(例如 IP/port 来自消息的来源;对于将是键和修饰符的 KeyPress 事件)。
您写道,另一个应用程序上的客户端将发送最多 4 个字节。有一个固定的字节数确实更方便(这可以通过在客户端填充消息来实现)或者一些终结符应该标记结束。
使用终止符(例如假设每条消息以换行结束),语法为:
t.BytesAvailableFcnMode = 'terminator';
t.Terminator = char(10); % or newline or recent versions of Matlab
和回调
function myTcpipCallback(obj,evt)
data=[obj.UserData ; fread(obj,obj.BytesAvailable,'char')]; %Read all available characters
%Just in case, check that we have not received more than one message
term=[0;find(data==obj.Terminator)];
for ii=1:length(term)-1
msg=data(term(ii)+1:term(ii+1));
%Do something with msg%
end
obj.UserData=data(term(ii)+1:end);
end
如果客户端快速发送数据,当回调函数在队列中等待时,一些额外的数据可能已经被缓冲,因此在执行它时,可能有几条消息可用。代码应该考虑到这种可能性。不幸的是,触发回调时缓冲区中可用的字节数不在事件数据中。
最后,如果您打算接收具有复杂规则的任意长度的消息以确定它是否完整,另一种可能性是逐个读取字节并在某处拥有自己的缓冲区,例如在对象用户数据中。
t.BytesAvailableFcnCount = 1; % n=1
t.BytesAvailableFcnMode = 'byte'; %Read after n bytes have been received
和回调:
function myTcpipCallback(obj,evt)
% Bufferize
obj.UserData=[obj.UserData ; fread(obj,1,'char')]; %Read 1 byte
% Check if the message if known
msg = obj.UserData;
if isComplete(msg) %
obj.UserData=[]; % empty buffer
processMessage(msg); % do something with message
end
end