2011-10-13 27 views
5

Tôi đang cố chuyển đổi mã PHP thành python.Chọn định dạng trong gói() bằng cách sử dụng mô-đun struct trong python

Tất cả giá trị được gửi theo thứ tự byte mạng (kết thúc lớn).

Về cơ bản, YÊU CẦU trong đặc tả giao thức là

enter image description here

và phản ứng là

enter image description here

Tương ứng với PHP Code (corresponding DOC) là:

$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); 

Tôi cố gắng để tìm mã tương ứng (for doc) trong 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)) 

Trong phản ứng, tôi sẽ nhận được TRANSACTION_ID cùng tôi đã gửi trong yêu cầu mà tôi không nhận được. Vì vậy, tôi đoán là, tôi không đóng gói bằng cách sử dụng định dạng chính xác.

Ngoài ra, tài liệu python không rõ ràng như của PHP. Giao thức chỉ định sử dụng định dạng Big Endian & Tài liệu PHP nêu rõ đó là định dạng dành cho Big-Endian.

Đáng buồn thay, tôi không thể hiểu định dạng nào cần sử dụng trong python. Hãy giúp tôi trong việc chọn định dạng sửa lỗi.

CHỈNH SỬA: Không nhận được bất kỳ phản hồi nào, vì vậy tôi sẽ nói nhiều hơn.

import struct 
import socket 
import random 

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

clisocket.sendto(packet, ("tracker.istole.it", 80)) 
res = clisocket.recv(16) 

print struct.unpack(">i", res[12:16]) 

Theo đặc điểm kỹ thuật giao thức, tôi phải được trả về cùng INTEGER.

+0

Hoàn doc cho giao thức là tại http://bittorrent.org/beps/bep_0015.html#udp-tracker-protocol –

+0

Một ví dụ cho thấy làm thế nào để lấy lại dữ liệu sử dụng giao thức có tại http://linux-junky.blogspot.com/2011/10/get-seeds-peers-completed-info-from.html –

Trả lời

3

Định dạng php pack functionN có nghĩa là số nguyên lớn 32-bit chưa ký. Định dạng Python struct.pack tương ứng là >L.

Hình ảnh bạn đã đăng cho giao thức hiển thị connection_id phải là số nguyên 64 bit (không dấu): định dạng Python struct.pack Q.

Vì vậy:

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

Tôi ước tôi có thể upvote bạn nhiều hơn một lần. CẢM ƠN NHIỀU. –

+1

Bạn có thể cho tôi biết tại sao bạn chọn Q (unsigned long long) cho số nguyên 64 bit và L (unsigned long) cho số nguyên 32 bit? Tôi cần phải biết điều này để tôi không gặp rắc rối khi làm điều tầm thường này. –

+1

64 bit là 8 byte. Cột thứ ba của bảng định dạng [struct.pack] (http://docs.python.org/library/struct.html#format-characters) có tiêu đề "Kích thước chuẩn" hiển thị các định dạng nào tương ứng với 8 byte. Các tùy chọn 8 byte là 'q',' Q' và 'd'. Vì chúng ta muốn các số nguyên không dấu, 'Q' là lựa chọn đúng đắn. Tương tự, 32 bit là 4 byte. Có bốn lựa chọn, 'i',' I', 'l',' L'. I * giả định * transaction_id nên được unsigned, do đó thu hẹp sự lựa chọn để 'I' hoặc' L'. Chúng tương đương nhau. Hoặc là một trong những công trình. – unutbu

0

Tính xác thực được mô tả trong §7.3.2.1 of the library reference. Bao bì lớn cấp có tiền tố >.

+0

Vì vậy, tôi nên sử dụng như thế nào? –

+1

[define: prefix] (http://www.google.com/search?q=define%3Aprefix) –

+1

http://sprunge.us/PBLf là mã của tôi nhưng tôi không được trả lại cùng một số nguyên TỪ PHP mã hoạt động tốt. –

Các vấn đề liên quan