2

I am trying to convert my code to Python 3 and I am having a problem about Struct while using problem. When I don't use variable while unpacking it gives me the result which I want, but when I use variable it doesn't give me the result that it needs to give.

I use def named "dataReceived" to get the data from socket. And I unpack it with struct.

Code with no variable (it gives true result) (result is 2) (packet is same with the packet that I get from socket):

packetFormat = unpack('!b', b'\x02\x01]\x00\x1c\x01\x01\xb0\x00\taMtIyfKal\x00\x07ActiveX\x00\x165.0 (Windows)-Netscape\x00)\xed\x06\x00\x00\x00@3407d2fbeefadbf85fa0f48bbac8337e026e0669b6be226156fd6fb4d575ef16\x00\xd9A=t&SA=t&SV=t&EV=t&MP3=t&AE=t&VE=t&ACC=t&PR=t&SP=f&SB=f&DEB=f&V=WIN 28,0,0,137&M=Adobe Windows&R=1280x1024&COL=color&AR=1.0&OS=Windows 8&ARCH=x86&L=tr&IME=t&PR32=t&PR64=t&PT=ActiveX&AVD=f&LFD=f&WD=f&TLS=t&ML=5.1&DP=72\x00\x00\x00\x00\x00\x00\x02\xca\x00\x00'[:1])[0]
print(packetFormat)

Code with variable (Gets the packet from def dataReceived) (it gives false result) (result is 98) (and both packets are same)

def dataReceived(this, packet):
 this.package = str(packet)
 packetFormat = unpack('!b', bytes(this.package, "utf-8")[:1])[0]
2
  • I just write there false, it needs to be "this.package". Commented Feb 4, 2018 at 9:47
  • 1
    Can you create a complete example that fails? Otherwise, it is very likely that the problem is somewhere else. Also, the form bytes('\x02...', 'utf-8') looks extremely dangerous and prone to break, because it depends on an encoding. Whats wrong with b'\x02...'? Commented Feb 4, 2018 at 9:47

1 Answer 1

3

Calling str on the bytes value that you receive does not do what you think it does.

This is the old, good, behaviour:

>>> bs = b'\x02'
>>> struct.unpack('!b', bs)
(2,)

In the new code, the bytes value is cast to a string:

>>> s = str(bs)

then it's unpacked:

>>> struct.unpack('!b', bytes(s, 'utf-8'))
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
struct.error: unpack requires a bytes object of length 1

Looks like there is something strange about the string value:

>>> s
"b'\\x02'"
>>> struct.unpack('!b', bytes(s, 'utf-8')[:1])
(98,)

Calling str on a bytes value gives us the bytes' repr as a string; to get the bytes as a string we need to call the bytes value's decode method. Note that your packet data appears to be encoded as latin-1, not utf-8. This doesn't matter for the first byte, but it does if you want to decode the entire bytestring.

>>> s = bs.decode('latin-1')
>>> struct.unpack('!b', bytes(s, 'latin-1'))
(2,)

So, don't call str on the bytes value that you unpack, either decode it or, better still, just leave it as bytes and avoid the unnecessary encoding and decoding. You can decode the bytes to a unicode string and store them on your instance though.

def dataReceived(this, packet):
 this.package = packet.decode('latin-1') # Store packet data as a unicode string
 packetFormat = unpack('!b', packet[:1])[0]
answered Feb 4, 2018 at 10:19
Sign up to request clarification or add additional context in comments.

2 Comments

What if I want to have the unpacked data in string?
I want the original data as a string.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.