想用t113-s3做个设备,收集老化台上can设备总线的数据,存起来,或者定时发送给局域网的pc。
请教,该怎么实现呢?
同事建议嵌入式linux设备上开个ftp服务器,pc上位机定时读取文件。
问了下gpt,说是sockete通信,于是搜了下,这类似串口发送接受?
请大家给点意见,怎么搞才好?
离线
PC上位机起一个socketserver,t113上起一个socketclient就可以,使用起来确实和串口很像,但是速率和稳定性要比串口好不少的。
那么,再请教下,socket通讯的话,需要pc和嵌入式linux互相知道对方的局域网地址吧,这个需要手动输入了吧?有没有简单的办法判别?实际应用中是一个PC,和多个嵌入式linux设备进行局域网通讯。
离线
不写代码,直接mount pc的共享文件夹,往里面存文件
离线
不写代码,直接mount pc的共享文件夹,往里面存文件
感觉一次性写入的话,可以考虑。但是如果想每隔几十秒传一次数据呢?
离线
@Gentlepig
不需要知道,只要PC和多个嵌入式设备都在同一网段就行了。比如server为[192.168.1.10],client为[192.168.1.55]和[192.168.1.86]等等,这样一般服务器起来后,client会自动连接到server
https://blog.csdn.net/weixin_45062087/article/details/118946561
对于APUE网络socket,我们需要了解就是server和client之间的通信建立过程。首先我们需要知道两台不同网段的pc是怎么通信的,当一台pc通过应用程序发一段消息过来给另一台pc时,pc获取到数据包之后就行拆包解析,这些都是操作系统内核的工作,对于server而言,需要告诉内核使用什么ip和端口来建立起服务,当有client接入时,内核先进行解析,得到client的ip和访问端口之后再给server(对应的应用程序),最后完成通信建立;对于client而言,需要知道server的ip和端口,获取ip来源主要是通过dns解析和人为获取,然后通过获取的ip和端口进行发送连接请求,最后完成通信。
我搜到的这个文章,我的理解是client连接server,需要知道对方地址。
最近编辑记录 Gentlepig (2023-12-18 13:43:36)
离线
@Meekdai
感谢。
意思是,client把局域网所有ip都列出来,然后挨个去尝试连接?
离线
@Meekdai
感谢。
意思是,client把局域网所有ip都列出来,然后挨个去尝试连接?
client先在局域网发一个UDP广播包,server收到后直接应答回去,这时client就拿到server的ip地址了,就可以与server建立连接
离线
Gentlepig 说:@Meekdai
感谢。
意思是,client把局域网所有ip都列出来,然后挨个去尝试连接?client先在局域网发一个UDP广播包,server收到后直接应答回去,这时client就拿到server的ip地址了,就可以与server建立连接
感谢。
离线
再请教下各位,目前通过udp广播,可以获取tcp server的地址了。然后通过tcp client连接tcp server后,可以互发数据。但有个新问题了,tcpsocket传输文件时,接收方不知道什么时候文件传输结束了,这该怎么解决好呢?
网上搜了下,简单的解决办法是,发送方,先发送4个字节表明接下来文件的长度,然后再发文件。
还有朋友说用http通讯。
该怎么解决这个问题好呢?
离线
@Gentlepig
传文件没有必要造轮子,直接用ftp就好,主机装一个ftp server,从机连接并使用ftp上传文件
或者使用ssh承载的sftp也可以
离线
@Gentlepig
传文件没有必要造轮子,直接用ftp就好,主机装一个ftp server,从机连接并使用ftp上传文件
或者使用ssh承载的sftp也可以
想定时传json数据,也许十秒就传一次。
FTP一半是传文件吧?我10秒传一个文件,ftp服务器收到后删除文件?
另http方式怎么样?
离线
用组播的方式,例如:PC端组播地址为:224.39.1.30 端口:6001 所有Linux设备设置组播地址为:224.39.1.30 端口6000,linux设备往地址224.39.1.30 端口:6001发数据,PC端就会收到数据,PC端往地址:224.39.1.30 端口6000 发数据时,所有Linux设备都会收到数据,可以不用在同一网段,Linux设备设置一个唯一序列号,上报数据时带上序列号,来区分是那台设备,PC端往设备发数据时也带上序列号,设备端收到数据后根据序列号来判断是不是给自己的数据
离线
struct ip_mreq mcast;
int optval = 0;
memset(&mcast, 0, sizeof(struct ip_mreq));
mcast.imr_interface.s_addr = INADDR_ANY; // //本地某一网络设备接口的IP地址。
mcast.imr_multiaddr.s_addr = inet_addr("224.39.1.30"); // 组播组的IP地址。
setsockopt(sktUdp, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(int)); // 设置可以发送广播包
setsockopt(sktUdp, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(struct ip_mreq)); // 设置组播地址
同时可以自己定义一个广播序列号,所有Linux设备收到这个广播序列号后都会执行PC端发的指令,这样可以用来查找局域网内的所有linux设备。或PC发一条指令,所有linux设备都执行某一动作,不用向每台设备都发一遍,具体应用,自己定义一套通讯协议就可以了。
离线
做个nfs 服务器,直接向里面写数据,这样最简单
离线
@Gentlepig
http post也可以,更规范一些,缺点是server要写一套,client的实现简单一些
或者可以试试mqtt,可以用现有的server,要存数据的一侧也做订阅就可以
离线
1. 服务器PC的IP必须是固定的.
2. 终端(也就是嵌入式端)通过路由器动态分配地址.
3. 用 udp 通信.
4. 终端在通信数据中表明自己是谁.
5. 所有的通信都基于: 一应一答, 由终端主动发起, PC端被动应答, 确保数据能收到.
6. 找本TCP/IP通信的书, 看一下简单的例子, 简单试一下,就行.
离线
建议用HTTP这种高级协议,我以前用socket写的C/S应用,问题多多,特别是网络不太好的时候比如WIFI
离线
目前的实现是,嵌入式linux上电后发送下udp广播,表明自己是tcp client,pc收到后自动返回udp信息,表明自己是tcp server,此时双方都知道了对方的ip地址。然后就开始tcp连接。当嵌入式板发现tcp断开时,启动个定时器,定时再发送udp广播信息。
但又遇到了个问题,现场最后是一台pc多个嵌入式linux设备,如何区分这几个嵌入式linux设备呢?
pc端可以用ip地址来区分,但是实际嵌入式设备是哪个地址,可能不好看出来。
想实现的是,设备区分为 01, 02, 03....这样的若干个设备。
但是,这样问题就又来了,如何配置设备的名称?
之前这么实现过,pc向t113-s3的usb的虚拟串口,发送个固定格式的数据,t113-s3这里,写个串口接收处理程序,将收到的数据存为一个配置文件。
不过觉得也不是很方便,t113-s3的usb口一般用来烧录程序,或adb push文件。
有什么更好的办法吗?求推荐。
最近编辑记录 Gentlepig (2024-01-12 17:03:38)
离线
我是这样处理的:
1:PC 运行一个广播程序,定期(N秒)向udp 5431端口广播一个消息。内容可以是正式消息的端口信息,比如:tcp://192.168.0.1:1234
2:client联上网后,打开这个udp 5431端口以接收pc的广播,
此时:client可以知道服务器ip,mac,
并从消息内容可以得知正式消息的端口。另开tcp联接传送数据。
3:PC 的正式消息处理程序 ,利用client的网卡mac来区分终端。
离线
@wxws
感谢分享经验,目前我是在设备系统目录里放了个json文件,里变有个描述设备名称的字符串。
最近编辑记录 Gentlepig (2024-01-17 14:04:37)
离线