Выбор формата в pack () с использованием модуля struct в python - PullRequest
5 голосов
/ 13 октября 2011

Я пытаюсь преобразовать код PHP в python.

Все значения отправляются в сетевом порядке байтов (с прямым порядком байтов).

По сути, запрос вспецификация протокола

enter image description here

и ответ

enter image description here

Соответствующий код PHP ( соответствующий DOC ):

$transaction_id = mt_rand(0,65535);
$current_connid = "\x00\x00\x04\x17\x27\x10\x19\x80";
$fp = fsockopen($tracker, $port, $errno, $errstr);
$packet = $current_connid . pack("N", 0) . pack("N", $transaction_id);
fwrite($fp,$packet);

Я пытаюсь найти соответствующий код ( для doc ) в python:

transaction_id = random.randrange(1,65535)
packet = "\x00\x00\x04\x17\x27\x10\x19\x80"
packet = packet + struct.pack("i", 0) + struct.pack("i", transaction_id)
clisocket =  socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
clisocket.sendto(packet, ("tracker.istole.it", 80))

В ответе я должен получить тот же транзакционный_идентификаторЯ отправил запрос, который я не получаю.Итак, я думаю, я не упаковываю, используя правильный формат.

Кроме того, документация по Python не так ясна, как в PHP.Протокол определяет использование формата Big Endian и документа PHP, в котором четко указано, что именно для Big-Endian.

К сожалению, я не мог понять, какой формат использовать в python.Пожалуйста, помогите мне в выборе формата Corrent.

РЕДАКТИРОВАТЬ: Не получая никаких ответов, поэтому я бы сказал больше.возвращается тот же INTEGER.

Ответы [ 2 ]

3 голосов
/ 13 октября 2011

Функция php pack format N означает 32-разрядное целое число без порядкового номера без знака.Соответствующий Python struct.pack формат >L.

Изображения, которые вы отправили для протокола, показывают, что connection_id должно быть 64-битным (без знака) целым числом: Python struct.packформат Q.

Итак:

clisocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
connection_id=0x41727101980
action=0
# transaction_id = random.randrange(1,65535)
transaction_id = 12345    
print(transaction_id)
# 12345

packet=struct.pack(">QLL",connection_id,action,transaction_id)
print(repr(packet))
# "\x00\x00\x04\x17'\x10\x19\x80\x00\x00\x00\x00\x00\x0009"

clisocket.sendto(packet, ("tracker.istole.it", 80))
res = clisocket.recv(16)
action,transaction_id,connection_id=struct.unpack(">LLQ",res)
print(action)
# 0
print(transaction_id)
# 12345 
print(connection_id)
# 2540598739861590271
0 голосов
/ 13 октября 2011

Порядковый номер описан в §7.3.2.1 справочной библиотеки .Упаковка Big-Endian имеет префикс >.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...