Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python套接字数据看起来像unicode,但无法翻译_Python_Unicode - Fatal编程技术网

Python套接字数据看起来像unicode,但无法翻译

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)

我是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.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)分隔字段:

  • 协议版本(如74)
  • Minecraft服务器版本(例如1.8.7)
  • 当日信息(如Minecraft服务器)
  • 当前玩家计数
  • 马克斯球员
  • 因此,去掉前三个字节,然后解码:

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