【问题标题】:python parse binary datapython解析二进制数据
【发布时间】:2014-11-12 20:26:53
【问题描述】:

我在 (windows) 中有一个以二进制格式发送日志的应用程序。 将其转换为字符串的 C# 代码是:

public static CounterSampleCollection Deserialize(BinaryReader binaryReader)
{
  string name = binaryReader.ReadString();  // counter name 
  short valueCount = binaryReader.ReadInt16();  // number of counter values

   var sampleCollection = new CounterSampleCollection(name);
   for (int i = 0; i < valueCount; i++)
   {
    // each counter value consists of a timestamp + the actual value 
    long binaryTimeStamp = binaryReader.ReadInt64();
    DateTime timeStamp = DateTime.FromBinary(binaryTimeStamp);
    float value = binaryReader.ReadSingle();

     sampleCollection.Add(new CounterSample(timeStamp, value));
  }
  return sampleCollection;
}

我有一个正在监听端口的 python udp 套接字,但不知道如何将接收到的二进制数据转换为字符串,以便进一步解析它。

请任何python专家帮我把那个函数转换成python函数,这样我就可以把我收到的数据转换成python。

到目前为止我的代码:

import socket

UDP_IP = "0.0.0.0"
UDP_PORT = 40001

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))

while True:
    data, addr = sock.recvfrom(8192) # buffer size is 8192 bytes
    print "[+] : ", data
    // this prints the binary 
    // convert the data to strings  ?? 

【问题讨论】:

    标签: c# python serialization binary


    【解决方案1】:

    我使用 struct 来解压二进制数据。 https://docs.python.org/2/library/struct.html 这是我用来从静态文件中解压缩数据的示例。

     import struct    
     comp = open(traceFile, 'rb')
     aData = comp.read()
     s = struct.Struct('>' +' i i i f f f d i H H')
     sSize = s.size
     for n in range(0, len(aData), sSize):
         print s.unpack(aData[n:n+sSize])
    

    【讨论】:

    • s = struct.Struct('>' +' iiifffdi H H') sSize = s.size while True: data, addr = sock.recvfrom(8192) # 缓冲区大小为 8192 字节 #print "***\n", data print "***\n" for n in range(0, len(data), sSize): print s.unpack(data[n:n+sSize]) == I get : struct.error: unpack 需要一个长度为 40 的字符串参数
    【解决方案2】:

    从套接字读取的示例如下:

    http://www.binarytides.com/receive-full-data-with-the-recv-socket-function-in-python/

    该参考资料中的 sn-p 为您提供了一些工具来编写所需的 Python 代码。 sn-p 使用 try ... except 子句和 sleep() 函数。该参考包含其他不错的提示。但问题的关键是二进制数据自然会转换为 python 字符串。

    while 1:
        #recv something
        try:
            data = the_socket.recv(8192)
            if data:
                total_data.append(data)
                #change the beginning time for measurement
                begin=time.time()
            else:
                #sleep for sometime to indicate a gap
                time.sleep(0.1)
        except:
            pass
    
    #join all parts to make final string
    s = ''.join(total_data)   # join accepts type str, so binary string is converted
    

    获得字符串“s”后,您需要根据 (1) 您拥有的数据对的分隔符、(2) 日期之间的分隔符和 (3) 日期字段的格式进行解析。我不知道你的二进制字符串是什么样子的,所以我只画一些你可能会用到的代码:

    results = []
    from datetime import datetime
    pairs = s.split('\n')    # assume that the pairs are linefeed-separated
    for pair in pairs:
        sdate, scount = pair.split(',')    # assume that a pair is separated by a comma
        timestamp = datetime.strptime(sdate, "%Y-%m-%d %H:%M:%S.%f")   # format must match sdate
        count = int(scount)
        results.append(timestamp, count)
    return results
    

    【讨论】:

    • pastebin.com/7fuq3NP5 -- 这是原始输出的样子.. join 无法将其转换为字符串。
    • 我刚刚注意到在您的 C# 代码中引用了 BinaryReader。看着这个并在“python BinaryReader”上搜索,我发现了一个命中,code.activestate.com/recipes/577610-decoding-binary-files,它使用 user3892766 的“struct”概念创建了一个 BinaryReader 类。我认为您需要手头有 UDP 规范才能将日期转换为年、月、日等。我现在有点不知所措,当您有解决方案时告诉我们。
    猜你喜欢
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多