Python套接字数据看起来像unicode,但无法翻译
我是PythonCGI新手,想从我的php项目中翻译Minecraft MOTD脚本,该项目使用套接字从服务器获取数据 以下是我的源代码:Python套接字数据看起来像unicode,但无法翻译,python,unicode,Python,Unicode,我是PythonCGI新手,想从我的php项目中翻译Minecraft MOTD脚本,该项目使用套接字从服务器获取数据 以下是我的源代码: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = "example.com" port = 25565 s.connect((host, port)) s.sendall(b"\xFE\x01", 0) msg = s.recv(4096)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "example.com"
port = 25565
s.connect((host, port))
s.sendall(b"\xFE\x01", 0)
msg = s.recv(4096)
s.close
print(msg)
它可以连接到服务器并发回MOTD数据,但看起来很奇怪
b'\xff\x00>\x00\xa7\x001\x00\x00\x001\x002\x007\x00\x00\x00B\x00u\x00n\x00g\x00e\x00e\x00C\x00o\x00r\x00d\x00 \x001\x00.\x008\x00.\x00x\x00-\x001\x00.\x001\x002\x00.\x00x\x00\x00\x00\xa7\x00f\x00\xa7\x001\x00A\x00n\x00o\x00t\x00h\x00e\x00r\x00 \x00B\x00u\x00n\x00g\x00e\x00e\x00 \x00s\x00e\x00r\x00v\x00e\x00r\x00\x00\x006\x00\x00\x002\x000\x000' --> -->
我试图找到它是什么,它看起来像UTF-16
我试着用这个来解决这个问题:
msg.decode('UTF-16')
但遗憾的是,它没有起作用
UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x30 in position 126: truncated data
args = ('utf-16-le', b'\xff\x00>\x00\xa7\x001\x00\x00\x001\x002\x007\...0v\x00e\x00r\x00\x00\x006\x00\x00\x002\x000\x000', 126, 127, 'truncated data')
encoding = 'utf-16-le'
end = 127
object = b'\xff\x00>\x00\xa7\x001\x00\x00\x001\x002\x007\...0v\x00e\x00r\x00\x00\x006\x00\x00\x002\x000\x000'
reason = 'truncated data'
start = 126
with_traceback = <built-in method with_traceback of UnicodeDecodeError object>
UnicodeDecodeError:“utf-16-le”编解码器无法解码位置126:截断数据中的字节0x30
args=('utf-16-le',b'\xff\x00>\x00\xa7\x001\x00\x00\x00\x00\x001\x002\x007\…0v\x00e\x00r\x00\x00\x006\x00\x00\x002\x000\x000',126、127,“截断数据”)
编码='utf-16-le'
结束=127
object=b'\xff\x00>\x00\xa7\x001\x00\x00\x001\x002\x007\…0v\x00e\x00r\x00\x00\x00\x006\x00\x00\x002\x000\x000'
原因='截断数据'
开始=126
带_回溯=
Python无法将这些代码翻译成文本,这让我很困惑。
我是编程新手,有没有解决这个问题的方法?您得到的是一个
截断数据
,因为您的数据确实被截断了。它的长度为127字节,从UTF-16解码它需要126或128字节的数据(即偶数字节)
删除尾随的\x00
字节并进行解码会产生以下结果:
>>> a = b'\xff\x00>\x00\xa7\x001\x00\x00\x001\x002\x007\x00\x00\x00B\x00u\x00n\x00g\x00e\x00e\x00C\x00o\x00r\x00d\x00 \x001\x00.\x008\x00.\x00x\x00-\x001\x00.\x001\x002\x00.\x00x\x00\x00\x00\xa7\x00f\x00\xa7\x001\x00A\x00n\x00o\x00t\x00h\x00e\x00r\x00 \x00B\x00u\x00n\x00g\x00e\x00e\x00 \x00s\x00e\x00r\x00v\x00e\x00r\x00\x00\x006\x00\x00\x002\x00'
>>> a.decode("utf-16")
u'\xff>\xa71\x00127\x00BungeeCord 1.8.x-1.12.x\x00\xa7f\xa71Another Bungee server\x006\x002'
>>>
根据,前三个字节是以下UTF-16BE字符串的分组ID和大小:
服务器到客户端
服务器用0xFF kick数据包进行响应。数据包以单字节标识符ff开始,然后是两字节标识符ff
big-endian short给出以下字符串的长度
人物。实际上,您可以忽略长度,因为服务器
在发送响应后关闭连接
在前3个字节之后,数据包是UTF-16BE字符串。它开始了
包含两个字符:§1,后跟空字符。在线上
它们看起来像00A70031000
余数为空字符(即00)分隔字段:
>>> data = b'\xff\x00>\x00\xa7\x001\x00\x00\x001\x002\x007\x00\x00\x00B\x00u\x00n\x00g\x00e\x00e\x00C\x00o\x00r\x00d\x00 \x001\x00.\x008\x00.\x00x\x00-\x001\x00.\x001\x002\x00.\x00x\x00\x00\x00\xa7\x00f\x00\xa7\x001\x00A\x00n\x00o\x00t\x00h\x00e\x00r\x00 \x00B\x00u\x00n\x00g\x00e\x00e\x00 \x00s\x00e\x00r\x00v\x00e\x00r\x00\x00\x006\x00\x00\x002\x000\x000'
>>> data[3:].decode('utf-16be').split('\x00')
['§1', '127', 'BungeeCord 1.8.x-1.12.x', '§f§1Another Bungee server', '6', '200']
您是如何在Php中解码响应的?@Bernhard在Php中,我使用UTF-16BE解码$Data=SubStr($Data,3)$数据=iconv('UTF-16BE','UTF-8',$Data);在我尝试通过
r=a[:-3]
删除轨迹后,它可以帮助我修复错误,但当我尝试print(r)
时,它只向我的浏览器输出一个主体背景。当它在Python上运行时,不是CGI,一切都很好。我真的不知道Python如何将数据打印到浏览器上。那么这是怎么发生的呢?嗯,我不太确定你使用的是什么设置。您使用什么在线运行python?字符串是unicode字符串,因此可能您必须使用特定于unicode的方法删除Windows 10上运行的最后3字节Apache 2.4.9+Python 3.x,网页使用utf-8格式OK,我找到了一个解决方案来修复它result=removedmsg.decode('utf-16')
打印(result.encode('utf-8'))
这里仍然存在问题,Minecraft MOTD在Minecraft 1.7之后开始使用JSON,这导致套接字解决方案只能从服务器获取旧MOTD
。谢谢你的解释:D