写作时间:2020-07-24
目录:
1.问题
2.代码
3.总结
正文:
1.问题
使用MATLAB,实现UDP传输,接收由网络发送过来的图像数据。
2.代码
以图像传输为例。
代码详细如下:
% UDP for Image Receive
%---------------------------------------------
% Revision History
% 2020-07-24
% 不要直接照抄,看懂后,才可以不变应万变!!!!
%---------------------------------------------
% UDP for Image Receive
%---------------------------------------------
% Revision History
% 20190916 优化了while(加入了ishandle作为while循环内的判断)
%---------------------------------------------
clc
clear
tic;
%----------------手动设置(保持和发送端一致)-------------
%%图像数据信息与图像打包方式(以下的需要提前与发包端设置统一)
row=512;%图像的行
col=640;%图像的列
pixelDepth=2;%Bytes 单个像素数据存储深度
BytePerPck=4096 ;%Bytes 一个包里面有多少Bytes
%------------------------------------------------------
pixelNum=row*col;%一个图像里面有多少像素
pixelNumPerPck=BytePerPck/pixelDepth;%一个包里面有多少像素
TSFL_Bytes=8;%Type_Serial_Frame_Len 信息所占的 Bytes
BytesPerImage=pixelNum*pixelDepth;%一个图像里面有多少Bytes
PckNumPerImage=BytesPerImage/BytePerPck;%一个图像里面有多少个包
BytePerPck_act=BytePerPck+TSFL_Bytes;%Bytes 实际上一个包有多少Bytes
dataNumPerPck=BytePerPck_act/2; %实际上一个包有多少个uint16的数据
%-----------------------------------------------------------
%-----------------------------------------------------------
%%UDP communication
u=udp('192.168.8.168', 'RemotePort', 8000, 'LocalPort', 8004);
u.InputBufferSize=4096*2048;%Bytes
u.DatagramTerminateMode='on';
u.Timeout=10;
fopen(u);
u.Status
drop_flag=1;%丢包标志
pckID=0;%第几包
Datapck_num=0;
Image=zeros(pixelNum,1);
hf1=figure;
set(hf1,'Name','UDP image');
%-----------------------------------------------------------
NumGetFrame=0;
while ishandle(hf1)
[PCKdata,cc]=fread(u,dataNumPerPck,'uint16');
if cc<4
disp('包内的数据不够!小于4个,重新再组帧');
continue
end
Type_pck=swapbytes(uint16(PCKdata(1)));
Serial_pck=swapbytes(uint16(PCKdata(2)));
if Type_pck==uint16(1)
pckID=0;
drop_flag=0;
Datapck_num=0;
elseif Type_pck==uint16(2)
vaildData_pck=uint16(PCKdata(5:end));
if length(vaildData_pck)~=uint16(pixelNumPerPck)
disp('数据包内的像素数据不够!重新再组帧');
continue
end
if drop_flag==0 && Serial_pck==pckID+1
aa=(uint32(Serial_pck)-1)*uint32(pixelNumPerPck)+1;
bb=uint32(Serial_pck)*uint32(pixelNumPerPck);
Image(aa:bb)=vaildData_pck;
Datapck_num=Datapck_num+1;
pckID=Serial_pck;
drop_flag=0;
else
drop_flag=1;%让下一包丢包的标志
end
else %Type_pck==3
if Datapck_num==PckNumPerImage
Image=swapbytes(uint16(Image));
Iin=reshape(Image,[col,row]);
Iin=Iin';
Iout=my_fun( Iin );% do your image process
clf;
pause(0.005);
imshow(uint8(Iout));%show your processed image resault
NumGetFrame=NumGetFrame+1;
disp(['散包组一帧显示',num2str(NumGetFrame)]);
end
drop_flag=0;
end
end
fclose(u);
u.Status
delete(u);
clear u;
toc;
%-----------------------------------------------------------
%-----------------------------------------------------------
close all;
disp('退出');
不要直接照抄,看懂后,才可以不变应万变!!!!
因为UDP包格式不一样!!
上述这段代码,再次分析下:
第一,理解UDP的创建于属性设置等
第二,最巧妙的是:如何设置“数据包”,以及“drop_flag(丢包标志),什么时候选择丢包,各个数据包如何组帧成完整图像帧。”
3.总结
以图像传输为例,实现了通过UDP的数据传输,然后再组包成单帧图像。
包格式为自己定义,所以在使用的时候,根据自己的需求更改包的格式。
注:
关于UDP。Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。
THE END~
另:2022-05-13
突然要用到,有同学问到,看上面代码看不懂,我举个简单实例,帮助大家理解,加点新内容。
code for udp tx &rx
% code for udp tx &rx
%(这段代码就是干框框,看看是怎么回事,以及注意事项就行了。)
%%%%read and write binary data over UDP
% 1. configure and connect to the server
echoudp('on',8001);
u=udp('127.0.0.1',8001);
u.OutputBufferSize=2400;
fopen(u);
disp(u.Status);
aa=u.Status;
% 2. writing binary data
fwrite(u,1:250,'int32')
u.ValuesSent
%3. configure inputbuffersize
fclose(u);
u.InputBufferSize=2400;% the inputbuffersize can be configured only when
% the object is not connected to the server or instrument
fopen(u);%now the propety is configured correctly
% you can reopen the connection to the server
%4. configure inputbuffersize
fwrite(u,1:250,'uint32');
u.Timeout=10;
data=fread(u,250,'uint32');
disp(u.ValuesReceived);
% disp(data);
% DatagramTerminate mode property incidate whether a read operation should be
% terminate when a datagram is received.
% by default,datagramterminate mode is on,which means that a read operation
% terminates when a datagram is received.
% to read multiple datagrams at once ,you can set datagramterminate mode
% to off .
fwrite(u,1:200,'uint32');
fwrite(u,1:100,'uint32');
fwrite(u,1:300,'uint32');
u.DatagramTerminateMode='off';
a=20;
data=fread(u,100+a,'uint32');
% size(data)
%5. cleanup
% if you are finished with UDP object ,disconnect it from memory
%
%
fclose(u);
disp(u.Status);
delete(u);
clear('u');
echoudp('off');
disp('ok');
干货如下,具体案例:
用netassit软件 和MATLAB 之间通信
1)netassit软件设置
2)MATLAB端,进行接收的一段简单代码demo
%MATLAB端,进行接收的一段简单代码
echoudp('on',8088)
u=udp('127.0.0.1', 'RemotePort', 8080, 'LocalPort', 8086);%
%MATLAB端口号和netassit端口号正好相反,但是地址是一样的哦。UDP就是这么简单。
u.InputBufferSize=4096*2048;%Bytes
u.DatagramTerminateMode='on';
u.Timeout=10;
fopen(u);
u.Status
hf1=figure;
set(hf1,'Name','UDP image');
while ishandle(hf1)
[A,cc]=fread(u,2,'uint16');
if cc~=0
fprintf('rx is %d\r\n',A);
disp('rx ok');
else
disp('rx fail');
end
end
echoudp('off')
fclose(u);
u.Status
delete(u);
clear u;
多说一句:
u=udp('127.0.0.1', 'RemotePort', 8080, 'LocalPort', 8086);
接下来,可以看到MATLAB接收到数据了。
好了,满足预想,就写这些了。
慢慢悟吧~
THE END~
【MATLAB-app】系列教程(含视频)00_csdn上第一套关于matlab appdesigner系列“视频课”来啦~~