通过python 3中的网络套接字接收二进制数据

时间:2022-08-26 19:40:30

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.

在我的网络课程中,我的实验室是让客户端以大端顺序接收5个熟悉的32位整数并对它们进行操作。我决定使用python,一切运行良好,但我收到奇怪的十六进制代码。

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

我可以很容易地转换大部分内容,但是x00o让我很困惑,228 435 475 492我认为4之后。你能帮我控制一下服务器的消息吗?

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)

1 个解决方案

#1


0  

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)
    • 使用[Python]:struct.unpack(fmt,buffer)来执行转换(也可以检查[SO]:Python struct.pack()行为,了解有关如何在内存中表示整数的更多详细信息)以及服务器响应)

    • Conversion is done to unsigned int ("I" format). Check the "Format Strings" section in on the (1st) above page
    • 转换为unsigned int(“I”格式)。检查上面第(1)页的“格式字符串”部分

    • 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 ints), 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)
    • 依赖于int是4个字节长的事实(我不想硬编码“IIIII”,想要使它更通用)。如果字符串长度不是4的整数(整数个整数),则最后不完整的int(最多3个字节)被丢弃(当然,填充字符串并转换“不完整”的更好方法)数据,但这不在问题范围内)

    • Returns a tuple containing the converted integers
    • 返回包含转换后的整数的元组

  • convert_data_to_ints:使用[Python]:struct.unpack(fmt,buffer)来执行转换(也可以检查[SO]:Python struct.pack()行为,以获取有关如何在内存中表示整数的更多详细信息 - 以及服务器响应)转换为unsigned int(“I”格式)。检查上面第(1)页的“格式字符串”部分依赖于int是4个字节长的事实(我不想硬编码“IIIII”,想要使它更通用)。如果字符串长度不是4的整数(整数个整数),则最后不完整的int(最多3个字节)被丢弃(当然,填充字符串并转换“不完整”的更好方法)数据,但是在问题范围之外)返回包含转换后的整数的元组

  • main:
    • Calls the above function on the data that you received from socket
    • 在从socket接收的数据上调用上述函数

    • As a bonus, it also converts it using little endian (but those values don't make much sense)
    • 作为奖励,它也使用little endian转换它(但这些值没有多大意义)

    • The data is a [Python]: Bytes Objects instance (I think socket.recv returns it in this form). If (I'm wrong and) it returns the data as a string, just use [Python]: str.encode(encoding="utf-8", errors="strict")
    • 数据是[Python]:Bytes Objects实例(我认为socket.recv以这种形式返回它)。如果(我错了)它将数据作为字符串返回,只需使用[Python]:str.encode(encoding =“utf-8”,errors =“strict”)

  • main:对从socket接收的数据调用上面的函数作为奖励,它也使用little endian转换它(但这些值没有多大意义)数据是[Python]:Bytes Objects实例(我认为) socket.recv以这种形式返回它)。如果(我错了)它将数据作为字符串返回,只需使用[Python]:str.encode(encoding =“utf-8”,errors =“strict”)

Output:

E:\Work\Dev\*\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)

#1


0  

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)
    • 使用[Python]:struct.unpack(fmt,buffer)来执行转换(也可以检查[SO]:Python struct.pack()行为,了解有关如何在内存中表示整数的更多详细信息)以及服务器响应)

    • Conversion is done to unsigned int ("I" format). Check the "Format Strings" section in on the (1st) above page
    • 转换为unsigned int(“I”格式)。检查上面第(1)页的“格式字符串”部分

    • 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 ints), 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)
    • 依赖于int是4个字节长的事实(我不想硬编码“IIIII”,想要使它更通用)。如果字符串长度不是4的整数(整数个整数),则最后不完整的int(最多3个字节)被丢弃(当然,填充字符串并转换“不完整”的更好方法)数据,但这不在问题范围内)

    • Returns a tuple containing the converted integers
    • 返回包含转换后的整数的元组

  • convert_data_to_ints:使用[Python]:struct.unpack(fmt,buffer)来执行转换(也可以检查[SO]:Python struct.pack()行为,以获取有关如何在内存中表示整数的更多详细信息 - 以及服务器响应)转换为unsigned int(“I”格式)。检查上面第(1)页的“格式字符串”部分依赖于int是4个字节长的事实(我不想硬编码“IIIII”,想要使它更通用)。如果字符串长度不是4的整数(整数个整数),则最后不完整的int(最多3个字节)被丢弃(当然,填充字符串并转换“不完整”的更好方法)数据,但是在问题范围之外)返回包含转换后的整数的元组

  • main:
    • Calls the above function on the data that you received from socket
    • 在从socket接收的数据上调用上述函数

    • As a bonus, it also converts it using little endian (but those values don't make much sense)
    • 作为奖励,它也使用little endian转换它(但这些值没有多大意义)

    • The data is a [Python]: Bytes Objects instance (I think socket.recv returns it in this form). If (I'm wrong and) it returns the data as a string, just use [Python]: str.encode(encoding="utf-8", errors="strict")
    • 数据是[Python]:Bytes Objects实例(我认为socket.recv以这种形式返回它)。如果(我错了)它将数据作为字符串返回,只需使用[Python]:str.encode(encoding =“utf-8”,errors =“strict”)

  • main:对从socket接收的数据调用上面的函数作为奖励,它也使用little endian转换它(但这些值没有多大意义)数据是[Python]:Bytes Objects实例(我认为) socket.recv以这种形式返回它)。如果(我错了)它将数据作为字符串返回,只需使用[Python]:str.encode(encoding =“utf-8”,errors =“strict”)

Output:

E:\Work\Dev\*\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)