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)
- Conversion is done to unsigned int (
"I"
format). Check the "Format Strings" section in on the (1st) 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 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) - Returns a tuple containing the converted integers
使用[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
- As a bonus, it also converts it using little endian (but those values don't make much sense)
- 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")
在从socket接收的数据上调用上述函数
作为奖励,它也使用little endian转换它(但这些值没有多大意义)
数据是[Python]:Bytes Objects实例(我认为socket.recv以这种形式返回它)。如果(我错了)它将数据作为字符串返回,只需使用[Python]:str.encode(encoding =“utf-8”,errors =“strict”)
convert_data_to_ints:使用[Python]:struct.unpack(fmt,buffer)来执行转换(也可以检查[SO]:Python struct.pack()行为,以获取有关如何在内存中表示整数的更多详细信息 - 以及服务器响应)转换为unsigned int(“I”格式)。检查上面第(1)页的“格式字符串”部分依赖于int是4个字节长的事实(我不想硬编码“IIIII”,想要使它更通用)。如果字符串长度不是4的整数(整数个整数),则最后不完整的int(最多3个字节)被丢弃(当然,填充字符串并转换“不完整”的更好方法)数据,但是在问题范围之外)返回包含转换后的整数的元组
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)
- Conversion is done to unsigned int (
"I"
format). Check the "Format Strings" section in on the (1st) 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 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) - Returns a tuple containing the converted integers
使用[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
- As a bonus, it also converts it using little endian (but those values don't make much sense)
- 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")
在从socket接收的数据上调用上述函数
作为奖励,它也使用little endian转换它(但这些值没有多大意义)
数据是[Python]:Bytes Objects实例(我认为socket.recv以这种形式返回它)。如果(我错了)它将数据作为字符串返回,只需使用[Python]:str.encode(encoding =“utf-8”,errors =“strict”)
convert_data_to_ints:使用[Python]:struct.unpack(fmt,buffer)来执行转换(也可以检查[SO]:Python struct.pack()行为,以获取有关如何在内存中表示整数的更多详细信息 - 以及服务器响应)转换为unsigned int(“I”格式)。检查上面第(1)页的“格式字符串”部分依赖于int是4个字节长的事实(我不想硬编码“IIIII”,想要使它更通用)。如果字符串长度不是4的整数(整数个整数),则最后不完整的int(最多3个字节)被丢弃(当然,填充字符串并转换“不完整”的更好方法)数据,但是在问题范围之外)返回包含转换后的整数的元组
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)