使用Python存储和重放二进制网络数据
我有一个用Python写的程序,它每秒发送556字节的数据,发送频率是50次。这个数据是用struct.pack()生成的,生成后会变成一个字符串,然后写入UDP套接字中。
除了发送这些数据,我还想把它们尽可能节省空间地保存到文件里,并且每条消息都加上时间戳,这样我以后可以重放这些数据。用Python实现这个目标的最佳方法是什么呢?
我考虑过使用logging对象,但还没弄清楚Python能不能读取日志文件,以便我可以重放数据。而且,我也不确定这个日志对象能否处理二进制数据。
如果有任何建议,我会非常感激!虽然Wireshark是一个选择,但我更希望用我的程序来存储数据,这样每次运行程序时都能自动开始新的数据文件。
2 个回答
为了方便重放,可以用一种紧凑的时间戳方式:把时间设置为自1970年1月1日以来的秒数,使用 time.time() 来获取这个时间,然后乘以50,因为你说你每秒要重复50次(这样算出来的单位,一般叫做“jiffy”,也就是五十分之一秒)。接着,把结果转成整数,减去你程序开始时测得的自1970年1月1日以来的jiffy的整数值,最后用 struct.pack
把结果打包成一个无符号整数,字节数根据你需要表示的时间长度来定——比如,用2个字节可以表示大约1200秒(20分钟),但如果你计划的时间更长,就需要用4个字节(3个字节我觉得太麻烦了;-)。
并不是所有操作系统的 time.time()
都能提供很好的精度,所以如果你需要在这些有限的操作系统上运行,可能需要用其他方法。(这当然是非常依赖操作系统的)。你需要支持哪些操作系统呢…?
另外,为了更紧凑,可以使用一个稍微高一点的乘数,比如10000,这样可以提高精度,每次存储与上一个时间戳的差值——因为这个差值应该和jiffy差不多(如果我理解你的需求没错的话),大约是200个“万分之一秒”,这样你就可以用一个无符号字节来存储,而且在存储未来重放的时间段时就没有限制了。当然,这还得依赖于 time.time()
的准确返回。
如果你的556字节的二进制数据很容易压缩,使用 gzip 来以压缩形式存储时间戳和数据流会很划算;不过,最好还是根据你实际的数据来评估一下效果。
Python的日志系统是为了处理人类能读懂的字符串而设计的,使用起来也很简单,可以根据需要轻松开启或关闭,适合开发者或者其他人运行你的程序时使用。不过,不要把它用在那些你的应用程序总是需要输出的内容上。
存储数据最简单的方法就是把你通过网络发送的556字节的字符串直接写入一个文件。如果你想要时间戳,可以在每条556字节的信息前面加上发送的时间,把时间转换成整数,然后用struct.pack()
打包成4或8个字节。具体的方法会根据你的需求而不同,比如你需要多精确的时间,或者你需要的是绝对时间还是相对于某个参考点的时间。