简体   繁体   中英

python parse binary data

I have an application in (windows) that sends logs in binary format. The c# code to convert that to strings is:

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;
}

I have a python udp socket that is listening to the port, but don't know how to convert the binary data I am receiving into strings so that I can parse it further.

Can any python expert please help me to convert that function into python function, so that I can convert the data I receive into python.

My code so far:

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  ?? 

I use struct to unpack binary data. https://docs.python.org/2/library/struct.html here's an example I use to unpack the data from a static file.

 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])

An example of reading from sockets is covered in the following:

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

A snippet from that reference gives you some tools for writing the Python code you want. The snippet uses the try ... except clause and sleep() funciton. The reference contains other nice tips. But key to your question is that the binary data naturally converts to a python string.

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

After you have string "s", you need to parse based on (1) the separator for the data pair that you have, (2) the separator between date and (3) the format of the date field. I do not know what your binary string looks like, so I will just sketch some code that you might use:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM