【问题标题】:Receiving binary data through network sockets in python 3在 python 3 中通过网络套接字接收二进制数据
【发布时间】:2018-01-29 18:47:21
【问题描述】:

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

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

我可以轻松转换其中的大部分,但 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)

【问题讨论】:

  • 如果缓冲区中的一个字节的值对应于一个可打印的字符,Python 在将缓冲区打印为字符串时将其显示为该字符。如果该值与可打印字符不匹配,Python 会将字节显示为 \x 前缀后的两个十六进制数字。因此,您的\x00o 表示一个值为 0 的字节,后跟一个值为字符 'o' 的值的字节。该字节的数值为ord('o'),即十进制111,十六进制6f。

标签: python sockets networking binary hex


【解决方案1】:

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()

注意事项

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

输出

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)

【讨论】:

    猜你喜欢
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 2012-08-23
    相关资源
    最近更新 更多