前言
目前的正在做的项目是打算把ARM端的数据传到PC上好做算法,考虑的方案是ARM使用python,PC端使用matlab,用TCP或者UDP协议传输,先写了几个简单的例程,试了试效果,中途遇到了一些问题,本来关于python和matlab之间的网络通信的资料就挺少的,所以在博客上记录一下(需要注意,我这里的python使用的是3.5,所以在语法上和2.7略有不同,比如网络传输的时候,不能传输str,而是要改为bytes)。
UDP方法
此时python是server端,matlab是client端。一开始遇到了一些问题,UDP传来的数据实在是太少了,后来才知道是matlab里面有一个InputBufferSize属性需要设置,将其设置大了后就好了。matlab还有一个需要注意的点是图片刷新问题,我发现不加上pause,matlab不会刷新图片的,加上pause后,图片就能实时刷新了。
python的代码
import socket
import time
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#ipv4,udp
sock.bind(('192.168.192.102',54377))#UDP服务器端口和IP绑定
buf, addr = sock.recvfrom(40960)#等待matlab发送请求,这样就能获取matlab client的ip和端口号
print(addr)
a=[x for x in range(40960,41160)]
while True:
a=[x + 1 for x in a]
s=str(a)#将数据转化为String
sock.sendto(bytes(s, encoding = "utf8") ,addr)#将数据转为bytes发送给matlab的client
print(s)
time.sleep(1)
sock.close()
matlab的代码
clc
clear
data_all=[];%用于存储所有的数据
u = udp('192.168.192.102', 54377, 'Timeout', 60,'InputBufferSize',10240);%连接这个ip和这个端口的UDP服务器,60秒超时,缓冲大小1024
fopen(u);
fwrite(u,'get');%发送一段数据给udp服务器。服务器好知道matlab的ip和端口
while(1)
receive = fread(u, 40960);%读取UDP服务器传来的数据
data=str2num(char(receive(2:end-1)')); %将ASCII码转换为str,再将str转换为数组
data_all=[data_all;data];
data
pause(0.0001);
plot(data)
end
fclose(u);
delete(u);
TCP方法
在使用UDP测试的时候,在自己的电脑上自环测试效果是非常好的,但是放到ARM上后,通过网络的传输,会出现或多或少的丢包现象,导致我data的数据和data_all的数据维数可能不齐,程序就崩了,所以才选择了稳定性更好的TCP方法。需要注意的是,TCP的fread后面的大小,一定要小于等于python发过来的实际大小,这样虽然后面有可能会收不到,但程序可以正常运行,否则会发生错误,程序死在fread上。所以python可以后面稍微多发一些冗余数据,保证前面能收到。问题解决了,参考了MATLAB中文论坛的帖子,修改了matlab代码,修改前和修改后的代码我都贴上好做对比。
python代码
import socket
import time
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#IPV4,TCP协议
sock.bind(('192.168.192.102',54377))#绑定ip和端口,bind接受的是一个元组
sock.listen(5)#设置监听,其值阻塞队列长度,一共可以有5+1个客户端和服务器连接
a=[x for x in range(40960,41160)]
print("start server")
while True:
a=[x + 1 for x in a]
s=str(a)#将数据转化为String
connection, address = sock.accept()#等待客户请求
print("client ip is:",address)#打印客户端地址
buf = connection.recv(40960)#接收数据,并存入buf
connection.send(bytes(s, encoding = "utf8"))#发送数据
print(s)
connection.close()#关闭连接
time.sleep(1)
sock.close()#关闭服务器
matlab代码(修改前,有小bug,接收的数据必须小于等于发送的数据)
clc
clear
data_all=[];%用于存储所有的数据
t = tcpip('192.168.192.102', 54377, 'Timeout', 60,'InputBufferSize',10240);%连接这个ip和这个端口的TCP服务器,60秒超时,缓冲大小10240
while(1)
fopen(t);
fwrite(t,'get');%发送一段数据给tcp服务器。服务器好知道matlab的ip和端口
receive = fread(t, 1024);%读取tcp服务器传来的数据,这里的数据要小于接收的数据,否则会出错
fclose(t);
data=str2num(char(receive(2:end-1)')); %将ASCII码转换为str,再将str转换为数组
data_all=[data_all;data];
data
pause(0.0001);
plot(data)
end
delete(t);
matlab代码(修改后)
clc
clear
data_all=[];%用于存储所有的数据
t = tcpip('192.168.192.102', 54377, 'Timeout', 60,'InputBufferSize',10240);%连接这个ip和这个端口的UDP服务器
%t.BytesAvailableFcnMode='byte'
while(1)
fopen(t);
fwrite(t,'get');%发送一段数据给tcp服务器。服务器好知道matlab的ip和端口
while(1) %轮询,直到有数据了再fread
nBytes = get(t,'BytesAvailable');
if nBytes>0
break;
end
end
receive = fread(t,nBytes);%读取tcp服务器传来的数据
%fread(t);
fclose(t);
data=str2num(char(receive(2:end-1)')); %将ASCII码转换为str,再将str转换为数组
data_all=[data_all;data];
data
pause(0.0001);
plot(data)
end
delete(t);