Reputation: 13
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]
Upvotes: 2
Views: 1050
Reputation: 55589
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]
Upvotes: 3