简体   繁体   English

PHP和Python解压缩从同一来源返回不同的结果

[英]PHP and Python unpack return different results from same source

I cannot seem to get even vaguely the same data from the Python (Which I would prefer to use) and PHP (Which works fine, coded by the host of the website) scripts. 我似乎甚至无法从Python(我更愿意使用)和PHP(工作正常,由网站托管的代码)脚本中获得相同的数据。

PHP connects to the same location as the Python script. PHP连接到与Python脚本相同的位置。

And before anyone jumps the gun, I know the python script only retrieves a part of the data. 而且在有人跳枪之前,我知道python脚本只能检索部分数据。 But I can't get even vaguely the same data from the server. 但是我什至无法从服务器获得相同的数据。

Python: 蟒蛇:

import socket, struct

host,port = 'baystation12.net', 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send('status\r\n')
data = s.recv(1024)
s.close()
print 'Received:', repr(data) # >>> Received: '\x00\xc7\x00\x07\x02\xadj\x00\x00\x1c\xf6'
cache,form,listy = "",">H",[]
for i in data:
    if cache != "":
        listy.append(struct.unpack(form,cache+i))
    else:
        cache = i
print "Unpacked:",listy # >>> Unpacked: [(199,), (0,), (7,), (2,), (173,), (106,), (0,), (0,), (28,), (246,)]


text = ""
for i in listy:
    text += chr(i[0])
print "Text:",text # >>> Text: Ç
#Shows up incorrectly when I try to copy it.

PHP: PHP:

#!/usr/bin/php
<?php
function export($addr,$port,$str)
{
    if($str{0} != "?") $str = ("?" . $str);
    $query = "\x00\x83" . pack("n",strlen($str)+6) . "\x00\x00\x00\x00\x00" . $str . "\x00";
    $server = socket_create(AF_INET,SOCK_STREAM,SOL_TCP) or exit('Unable to create export socket; ' . socket_strerror(socket_last_error()));
    socket_connect($server,$addr,$port) or exit('Unable to establish socket connection; ' . socket_strerror(socket_last_error()));
    $bytessent = 0;
    while($bytessent < strlen($query))
    {
        $result = socket_write($server,substr($query,$bytessent),strlen($query)-$bytessent);
        if($result === FALSE) return('Unable to transfer requested data; ' .  socket_strerror(socket_last_error()));
        $bytessent += $result;
    }
    $resbuf = '';
    while( socket_recv($server, $message,1,0 )){
       $resbuf .= $message;
    if(strpos($resbuf,"&end")!=FALSE)
      {
       echo $resbuf;
       socket_close($server);
       return($resbuf);
      }
    echo $message;
    };
    echo $resbuf."\n";
    socket_close($server);
}
export("localhost","8000","status");
?>

PHP's output: PHP的输出:

version=Baystation+12&mode=extended&respawn=0&enter=1&vote=1&ai=1&host&players=5&player0=CompactNinja&player1=Sick+trigger&player2=SweetJealousy&player3=Cacophony&player4=Anchorshag&end

Any idea why Python gives out nonsensical characters when unpacking the data, while PHP gives out the above. 知道为什么Python在解压缩数据时会给出荒谬的字符,而PHP会给出上述内容。

You're not sending the same query to your server in python. 您不是使用python将相同的查询发送到服务器。

In python you're sending status 在python中,您正在发送status

In PHP you're sending something like \\x00\\x83\\x00\\x0d\\x00\\x00\\x00\\x00\\x00\\x00?status\\x00 在PHP中,您发送的是\\x00\\x83\\x00\\x0d\\x00\\x00\\x00\\x00\\x00\\x00?status\\x00

If you change your python to more closely imitate the PHP then it works a lot better: 如果您更改python使其更接近于模仿PHP,那么它的效果会更好:

import socket, struct

host,port = 'baystation12.net', 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

senddata = "?status"
query  = '\x00\x83' + struct.pack(">H", len(senddata)+6) + '\x00'*5 + senddata + '\x00'
s.send(query)

data = s.recv(1024)
print `data`

When I tried that, it printed 当我尝试时,它打印

'\x00\x83\x00\xe9\x06version=Baystation+12&mode=traitor&respawn=0&enter=1&vote=1&ai=1&host&players=7&player0=Kosherman&player1=Ghazkull&player2=Doug+H.+Nuts&player3=Lord+Braindead&player4=KirbyElder&player5=Master+of+Apples&player6=Cacophony&end=%23end\x00'

Which looks pretty similar to what the PHP was getting. 看起来很像PHP。

Try listy.append(struct.unpack(form,cache+i)[0]) 试试listy.append(struct.unpack(form,cache+i)[0])

You're ending up with a list of 1-element tuples rather than the a list of numbers. 您最终得到的是一个包含1个元素的元组的列表,而不是一个数字列表。

From the docs: http://docs.python.org/library/struct.html#struct.unpack 从文档中: http : //docs.python.org/library/struct.html#struct.unpack

 struct.unpack(fmt, string) 

Unpack the string (presumably packed by pack(fmt, ...)) according to the given format. 根据给定的格式解压缩字符串(大概由pack(fmt,...)打包)。 The result is a tuple even if it contains exactly one item. 结果是一个元组,即使它只包含一个项目。 The string must contain exactly the amount of data required by the format (len(string) must equal calcsize(fmt)). 该字符串必须完全包含该格式所需的数据量(len(string)必须等于calcsize(fmt))。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM