prob with struct and byte order

Grant Edwards grante at visi.com
Mon Jul 24 13:39:54 EDT 2006


On 2006-07-24, Steve Holden <steve at holdenweb.com> wrote:
> nephish at xit.net wrote:
>> hello there, all.
>> 
>> i have a difficult app that connects to a server to get information for
>> our database here.
>> this server is our access point to some equipment in the field that we
>> monitor.
>> 
>> the messages come in over a socket connection. And according to their
>> (very limited) documentation, are set up in a particular order. like
>> this
>> 
>> STX [length indicator] [message type] [message body] ENX
>> 
>> length indicator = length of the message body in 4 bytes
>> message type = the code for what type of message is being sent
>>    for example 200 = login
>> message body = the actual command to send to the server
>> 
>> STX and ENX are the values assigned to start and stop a message.
>> they are literally 'STX' and 'ENX'

> I believe you, but this is clearly a perversion of the
> single-character "start of transmission" and "end of
> transmission" that are part of the ASCII alphabet. So the
> protocol designer may have been inexperienced, and the
> documentation may be confused ...

I had the same reaction: surely he means the frame is delmited
at the beginning by the ASCII STX character (0x02) and the end
by the ETX character (0x03).  

If somebody is indeed sending the three character string "STX"
to mark the beginning of a frame and "ENX" to mark the end,
then they're seriously confused (and can't spell).

>> when i capture a message i can print it to the screen and the 'STX' at
>> the beginning and the 'ENX' at the end are discernable, but the rest of
>> the message looks like this..
>> 
>> \x00\x00\x00,\x00\x00\x00\e17758\x00\x00   and so on and so forth...
>> with some commas and other symbols in there. (the e before the 17758
>> has a little hat on it)

So the unit number is an ASCII string.  Firstly, I'd recommend
printing the message in hex:

print ' '.join(["%02.2x" % ord(b) for b in message])

That should make it easier to figure how which byte indexes
contain the info you're looking for.

>> If i print it out to a text file, i get this...
>> STXNULNULNULea17758NULLNULL etc..

I'm a but baffled how the string shown above would get printed
like that.

> The "\x00" is the Python repr() of a single-byte string containing a 
> null byte (i.e. a byte whose decimal value is zero).
>
>> now the 17758 is significant because it is the actual unit number of
>> the machine we want to monitor. I just dont know how to extract the
>> real values out of this message.

What is meant by "real values"?

>> anyone have an idea where to start? i have experimented with
>> struct, but do not know enough about it. Does anyone know a
>> good tutorial about learning byte codes and such.

What are "byte codes"?

>> The docs on pythons website explain the module well, but i
>> still do not know what to do with it.

You've got to figure out the format and location within the
message of the objects you care about.  Once you know that, you
use struct to pull out the appropriate bytes and convert them
into Python objects.

If you know (or suspect) there are IEEE 754 32-bit floating
point values in the message, then start converting all of the
possible 4-byte chunks into Python floats (using both endian
conventions) until you see numbers you recognize.

Same for 64-bit floats and interger values of various sizes.

-- 
Grant Edwards                   grante             Yow!  HUMAN REPLICAS are
                                  at               inserted into VATS of
                               visi.com            NUTRITIONAL YEAST...



More information about the Python-list mailing list