我正在使用python-2.7处理IPv6和UDP套接字。我特别关注IPv6多播ff02::1
,其中每个链路本地地址设备(带fe80::
)都响应来自中央服务器实体的查询。
我将微控制器连接到这些设备上,这些设备需要.ihex
(Intel Hex)形式的程序。该文件的一个片段如下:
:103100005542200135D0085A8245381131400031EE
:103110003F4002000F9308249242381120012F8370
:103120009F4F1E390011F8233F4036000F930724AC
我认为应该使用struct
和pack
和unpack
等函数,但我不确定发送这样一个Kbs大小的ihex文件是否能解决这个问题。
我可以做一些类似的事情吗:
#!/usr/bin/env python
from struct import pack, unpack
import socket
. # Create a UDP socket and Bind it..
.
myHexCode = open("Filename.ihex")
dataToSend = struct.pack('Paramaters for packing', myHexCode)
.
. Send data to socket..
包装参数是什么?(我应该为十六进制文件执行!
、Big或small Endian >
或<
吗?)
备注
我不能使用
scp
和sftp
,因为这两种协议都在TCP上工作,不支持多播,而且我工作的环境中网络损耗可能更高(无线介质)此外,我是否应该按照此查询的建议将Intel Hex文件转换为二进制文件,然后打包二进制文件?
使用UDP和多播将文件发送给多个消费者似乎充满了问题——除非整个文件适合一个数据包。UDP数据包可能由于多种原因而被丢弃,而且您已经说过网络有损。每个消费者都需要有一种方法来跟踪并通知发送者丢失的数据包。
话虽如此,这当然是可行的。一个想法是:构建一个初始数据包,您可以多次多播,可能其间会有随机延迟(以确保所有站点都能接收到它)。这个初始数据包实际上就像"即将发送新程序-预计N个后续记录数据包")。
然后发送N个数据包,每个数据包可能发送两次。在每个数据包中放入一个识别序列号,并让消费者跟踪他们收到的数据包。在一段延迟后(或当所有数据都已收到时),让每个消费者用一个状态包做出响应,说"我收到了所有N个数据包"或"我没有收到记录5、98、144和3019"(或基于损失的任何合适方案)。
然后,发送者可以收集这些丢失的记录ID并重新发送这些ID,直到所有消费者都满意他们已经收到了整个文件。
对于将它们打包到数据报中,我认为发送"英特尔十六进制"还是二进制并不重要。在任何一种情况下,您都希望将它们作为字节流发送。二进制会更小,因此需要更少的数据包,但在发送过程中没有其他区别。出于同样的原因,您选择的字节顺序不会有什么不同。对于简单的字节流,您根本不需要使用struct
来打包它们。你可以直接发送。
注意:python3区分
bytes
和str
类型,因此您需要以"二进制"模式打开文件,以便在python3。
然而,如果如上所述,您最终在每个数据包中发送了一个序列号,则需要以某种方式格式化该序列号。您可以将数字格式化为ascii字符串,并且不需要struct.pack
。或者,如果您将其格式化为二进制,则需要选择一种打包格式。传统上,网络数据包使用"网络字节顺序"(实际上与big-endian相同),但这只是一种惯例。
如果我这样做,我可能会用来构建每条记录
- 记录类型(二进制,一个字节--区分这是一个数据包)
- 记录ID(二进制,两个字节--序列号[或更大,取决于文件的大小])
- 记录数据长度(二进制,两个字节表示记录数据字段的长度)
- 记录数据(二进制,N字节)
然后,您可以使用以下内容创建有效载荷:
payload = struct.pack("!BHH", record_type, record_id, len(record_data))
+ record_data
在这里,我们创建了一个5字节的字符串,其中struct.pack
包含"头"字段(使用网络字节顺序打包),然后简单地附加已经是字节字符串的record_data。