简体   繁体   中英

Receiving binary data through network sockets in python 3

In my networking class a lab i have is to make a client to receive 5 familiar 32-bit integers in big endian order and to intemperate them. I decided to use python and everything works well enough but i am receiving strange hex code.

\\x00\\x00\\x00o\\x00\\x00\\x00\\xe4\\x00\\x00\\x01\\xb3\\x00\\x00\\x01\\xdb\\x00\\x00\\x01\\xec

I can convert most of it easily but the x00o is really confusing me, 228 435 475 492 where the 4 after that I believe. Can you help me intemperate the server message?

import socket 
import sys
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
    print('Failed to create socket')
    sys.exit()
print('Socket Created')

host = 'localhost'
port = 5071

try:
    remote_ip = socket.gethostbyname(host)

except socket.gaierror:
    #could not resolve
    print('Hostname could not be resolved. Exiting')
    sys.exit()

s.connect((remote_ip , port))

print('Socket Connected to ' + host + ' on ip ' + remote_ip)

reply = s.recv(4096)

print(reply)

code.py :

import sys
import struct


def convert_data_to_ints(data, big_endian=True):
    int_count = len(data) // 4  # Assuming uint is 4 bytes long !!!
    fmt = ">" if big_endian else "<"
    fmt += "I" * int_count
    return struct.unpack(fmt, data[:int_count * 4])


def main():
    print("Python {} on {}\n".format(sys.version, sys.platform))
    data = b"\x00\x00\x00o\x00\x00\x00\xe4\x00\x00\x01\xb3\x00\x00\x01\xdb\x00\x00\x01\xec"
    ints_be = convert_data_to_ints(data)
    print("Big endian: {}".format(ints_be))
    ints_le = convert_data_to_ints(data, big_endian=False)
    print("Little endian: {}".format(ints_le))


if __name__ == "__main__":
    main()

Notes :

  • convert_data_to_ints :
    • Uses [Python]: struct. unpack ( fmt, buffer ) to perform the conversion (might also check [SO]: Python struct.pack() behavior for more details on how integers are being represented in memory - and also in the server response)
    • Conversion is done to unsigned int ( "I" format). Check the " Format Strings " section in on the (1 st ) above page
    • Relies on the fact that int is 4 bytes long (I didn't want to hardcode the "IIIII" , wanted to make it more general). If the string length is not a multiple of 4 (an integral number of int s), the incomplete int at the end (at most 3 bytes) is discarded (of course, a nicer way to pad the string and also convert the "incomplete" data, but that's outside the question scope)
    • Returns a tuple containing the converted integers
  • main :

Output :

 E:\\Work\\Dev\\StackOverflow\\q048508018>"c:\\install\\Python\\3.4.3\\x86\\python.exe" code.py Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32 Big endian: (111, 228, 435, 475, 492) Little endian: (1862270976, 3825205248, 3003187200, 3674275840, 3959488512) 

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