Python发送十六进制数据,高效存储

时间:2018-07-09 13:31:29

标签: python

我目前正在从事一个涉及一些非常远程的数据收集的项目。每天结束时,简短的摘要都会通过卫星连接发送回服务器。

由于通过卫星发送数据非常昂贵,我希望数据尽可能紧凑。另外,我正在使用的服务仅允许以以下两种格式发送数据:ASCII,十六进制。我将发送的大多数数据都由浮点数组成,浮点数的精度应尽可能高而不会占用太多空间。

下面我有当前正在使用的版本,但是应该有一种更有效的方式来存储数据。任何帮助将不胜感激。

import ctypes

#------------------------------------------------------------------
#This part is known to the client as well as the server
class my_struct(ctypes.Structure):
    _pack_ = 1
    _fields_ = [('someText', ctypes.c_char * 12),
                ('underRange', ctypes.c_float),
                ('overRange', ctypes.c_float),
                ('TXPDO', ctypes.c_float)]

def print_struct(filled_struct):
    d = filled_struct
    for name,typ in d._fields_:
        value = getattr(d, name)
        print('{:20} {:20} {}'.format(name, str(value), str(typ)))

#------------------------------------------------------------------
# This part of the code is performed on the client side
#Filling the struct with some random data, real data will come from sensors
s = my_struct()
s.someText = 'Hello World!'.encode()
s.underRange = 4.01234
s.overRange = 4.012345
s.TXPDO = 1.23456789

#Rounding errors occurred when converting to ctypes.c_float
print('Data sent:')
print_struct(s)

data = bytes(s) #Total length is 24 bytes (12 for the string + 3x4 for the floats)
data_hex = data.hex() #Total length is 48 bytes in hexadecimal format

#Now the data is sent over a satellite connection, it should be as small as possible
print('\nLength of sent data: ',len(data_hex),'bytes\n') 

#------------------------------------------------------------------
# This part of the code is performed on the server side
def move_bytes_to_struct(struct_to_fill,bytes_to_move):
    adr = ctypes.addressof(struct_to_fill)
    struct_size = ctypes.sizeof(struct_to_fill)

    bytes_to_move = bytes_to_move[0:struct_size]
    ctypes.memmove(adr, bytes_to_move, struct_size)

    return struct_to_fill

#Data received can be assumed to be the same as data sent
data_hex_received = data_hex
data_bytes = bytes.fromhex(data_hex_received)
data_received = move_bytes_to_struct(my_struct(), data_bytes)

print('Data received:')
print_struct(data_received)

1 个答案:

答案 0 :(得分:2)

我不知道您是否使事情变得有些复杂。 struct模块将使您可以做很多事情,但更简单:

struct.pack("fffs12", 4.01234, 4.012345, 1.23456789, 'Hello World!'.encode())

这当然取决于您知道字符串的长度,但是您也不必在意:

struct.pack("fff", 4.01234, 4.012345, 1.23456789) + 'Hello World!'.encode()

但是,关于更有效地保存内容: 您对数据了解的越多,可以采取的捷径就越多。 字符串仅是ascii吗?您可以将每个字符压缩为7位,甚至6位。 这可能会使您的12个字节的字符串变为9。

如果您知道浮标的范围,则也可以对其进行修剪。

如果您可以发送更大的批次,压缩也可能会有所帮助。