还是关于PHP的二进制流问题
之前发了一帖: http://bbs.csdn.net/topics/391024843
版主给了回答,也能够解析出来,但却发现出来的结果与真实结果完全不一样,比如服务器返回给我的是: ip: 107.145.107.140, port: 26773
但我解析出来却变成了: ip: 46.48.46.48, port: 63271
这样就差的远了, 我用PHP去获取nodes信息,然后将nodes信息自己解析输出一遍,顺便把未解析数据发送给pthon解析一遍,然后两边对比,发现结果却不一样
PHP(使用了swoole):
<?php<br />$serv = new swoole_server('0.0.0.0', 6882, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);<br />$serv->set(array(<br /> 'worker_num' => WORKER_NUM,<br /> 'daemonize' => false,<br /> 'max_request' => MAX_REQUEST,<br /> 'dispatch_mode' => 2,<br /> 'debug_mode' => 1<br />));<br />$serv->on('Start', function($serv){<br /> echo "DHT Server start...\n";<br /> $nid = get_node_id();<br /><br /> $msg = array(<br /> 't' => entropy(2),<br /> 'y' => 'q',<br /> 'q' => 'find_node',<br /> 'a' => array(<br /> 'id' => $nid,<br /> 'target' => $nid<br /> )<br /> );<br /><br /> $serv->sendto(gethostbyname('router.bittorrent.com'), 6881, encode($msg));<br />});<br />$serv->on('Receive', function($serv, $fd, $from_id, $data){<br /> echo "New receive from ip: ";<br /> $msg = decode($data);<br /> $fdinfo = $serv->connection_info($fd);<br /> echo $fdinfo['remote_ip'] . "\n";<br /><br /> if($msg['y'] == 'r'){<br /> if(array_key_exists('nodes', $msg['r']))<br /> //$this->response_actions($msg, array($fdinfo['remote_ip'], $fdinfo['remote_port']));<br /> $nodes = decode_nodes($msg['r']['nodes']);<br /> foreach($nodes as $node){<br /> echo "nid: " . $node->nid . ", ip: " . $node->ip . ", port: " . $node->port . "\n";<br /> }<br /> $serv->sendto('127.0.0.1', 6813, $data);<br /> }<br />});<br /><br />function entropy($length=20){<br /> $s = '';<br /><br /> for($i=0;$i<$length;$i++)<br /> $s .= chr(mt_rand(0, 255));<br /><br /> return $s;<br /> }<br /><br />function get_node_id(){<br /> return sha1(entropy());<br /> }<br /><br />function get_neighbor($target, $nid){<br /> return substr($target, 0, 10) . substr($nid, 0, -10);<br /> }<br /><br />function encode($msg){<br /> return Bencode::encode($msg);<br /> }<br /><br />function decode($msg){<br /> return Bencode::decode($msg);<br /> }<br /><br />function decode_nodes($msg){<br /> $n = array();<br /> $length = strlen($msg);<br /><br /> // 由于每个node都为26位, 若总长度不等于26的倍数则直接返回<br /> if(($length % 26) != 0)<br /> return $n;<br /><br /> $i = 0;<br /><br /> while($i<$length){<br /> //$s = substr($msg, $i, 26);<br /> //$d = unpack('a20nid/Lip/Sport', $s);<br /> //var_dump($d);<br /> //$d = unpack('a20nid/lip/sport', $s);<br /> //var_dump($d);<br /> //$n[] = new Node($d['nid'], long2ip($d['ip']), $d['port']);<br /> $nid = substr($msg, $i, 20);<br /> var_dump($nid);<br /> $ip = substr($msg, $i+20, 4);<br /> var_dump($ip);<br /> $ip = long2ip(unpack('L', $ip)[1]);<br /> $port = substr($msg, $i+24, 2);<br /> var_dump($port);<br /> $port = unpack('s', $port)[1];<br /> var_dump($port);<br /> //$n[] = new Node($nid, $ip, $port);<br /><br /> $i += 26;<br /> }<br /><br /> return $n;<br /> }<br /><br />$serv->start();
python:
#!/usr/bin/env python<br />#encoding: utf-8<br /><br />import socket<br />from hashlib import sha1<br />from random import randint<br />from struct import unpack<br />from socket import inet_ntoa<br />from threading import Timer, Thread<br />from time import sleep<br />from collections import deque<br />from bencode import bencode, bdecode<br /><br />def decode_nodes(nodes):<br /> n = []<br /> length = len(nodes)<br /> if(length % 26) != 0:<br /> return n<br /><br /> for i in range(0, length, 26):<br /> nid = nodes[i:i+20]<br /> ip = inet_ntoa(nodes[i+20:i+24])<br /> ip2 = nodes[i+20:i+24]<br /> print ip2<br /> port = unpack("!H", nodes[i+24:i+26])[0]<br /> port2 = nodes[i+24:i+26]<br /> print port2<br /> print "decode_nodes: nid: %s, ip: %s, port: %s\n" % (nid, ip, port)<br /><br />class DHTServer():<br /> def __init__(self):<br /> self.ufd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)<br /> self.ufd.bind(("0.0.0.0", 6813))<br /><br /> def process_find_node_response(self, msg, address):<br /> nodes = decode_nodes(msg["r"]["nodes"])<br /><br /> for node in nodes:<br /> (nid, ip, port) = node<br /><br /> print "find_node: nid: %s, ip: %s, port: %s\n" % (nid, ip, port)<br /><br /> def run(self):<br /> while True:<br /> try:<br /> (data, address) = self.ufd.recvfrom(65536)<br /> msg = bdecode(data)<br /> self.on_message(msg, address)<br /> except Exception:<br /> pass<br /><br /> def on_message(self, msg, address):<br /> try:<br /> if msg["y"] == "r":<br /> if msg["r"].has_key("nodes"):<br /> self.process_find_node_response(msg, address)<br /> except KeyError:<br /> pass<br /><br />if __name__ == "__main__":<br /> # max_node_qsize bigger, bandwith bigger, spped higher<br /> dht = DHTServer()<br /> dht.run()
------解决思路----------------------
$s = 'P9LI9UagRY0oDfVScSnuyKZHmjRO68KLdlc/0sj1RqBFjSgN9VJxKe7IpkeaNE7rwot2Vz/SyPVGoEWNKA31UnEp7simR5o0TuvCi3ZXP/wj7jU8hMYdclU8RKIZNM7tvZSxt+rIH5A//CPuNTyExh1yVTxEohk0zu29lLG36sgfkD/8I+41PITGHXJVPESiGTTO7b2UsbfqyB+QP/9M6KfuKOE8aeW+E0SS7Ug7UHZlzEY+GuE//0zop+4o4Txp5b4TRJLtSDtQdmXMRj4a4T//TOin7ijhPGnlvhNEku1IO1B2ZcxGPhrhPk6NAzs25ZjxFKrQJrZEjbfkAhg8GYaAGuE+To0DOzblmPEUqtAmtkSNt+QCGDwZhoAa4T5OjQM7NuWY8RSq0Ca2RI235AIYPBmGgBrhPs9ltmz/1Jul2AA0wRDx0d4e2AFR4CzD2+A+z2W2bP/Um6XYADTBEPHR3h7YAVHgLMPb4D7PZbZs/9SbpdgANMEQ8dHeHtgBUeAsw9vgPajAE2YlZG+/uqPNCgQzuP6WjQ7fpv0NGuE=';<br />$s = base64_decode($s);<br />foreach(str_split($s, 26) as $s) {<br /> $r = unpack('a20n/Nip/np', $s);<br /> $r['ip'] = long2ip($r['ip']);<br /> print_r($r);<br />}
Array<br />(<br /> [n] => ????F E?(<br />?Rq)???G?4<br /> [ip] => 78.235.194.139<br /> [p] => 30295<br />)<br />Array<br />(<br /> [n] => ????F E?(<br />?Rq)???G?4<br /> [ip] => 78.235.194.139<br /> [p] => 30295<br />)<br />Array<br />(<br /> [n] => ????F E?(<br />?Rq)???G?4<br /> [ip] => 78.235.194.139<br /> [p] => 30295<br />)<br />Array<br />(<br /> [n] => ?ü#?5<??rU<D?4?í?”<br /> [ip] => 177.183.234.200<br /> [p] => 8080<br />)<br />Array<br />(<br /> [n] => ?ü#?5<??rU<D?4?í?”<br /> [ip] => 177.183.234.200<br /> [p] => 8080<br />)<br />Array<br />(<br /> [n] => ?ü#?5<??rU<D?4?í?”<br /> [ip] => 177.183.234.200<br /> [p] => 8080<br />)<br />Array<br />(<br /> [n] => ??Lè§?(á<i??D’íH;Pv<br /> [ip] => 101.204.70.62<br /> [p] => 6881<br />)<br />Array<br />(<br /> [n] => ??Lè§?(á<i??D’íH;Pv<br /> [ip] => 101.204.70.62<br /> [p] => 6881<br />)<br />Array<br />(<br /> [n] => ??Lè§?(á<i??D’íH;Pv<br /> [ip] => 101.204.70.62<br /> [p] => 6881<br />)<br />Array<br />(<br /> [n] => >N?;6?????&?D?·?<br /> [ip] => 60.25.134.128<br /> [p] => 6881<br />)<br />Array<br />(<br /> [n] => >N?;6?????&?D?·?<br /> [ip] => 60.25.134.128<br /> [p] => 6881<br />)<br />Array<br />(<br /> [n] => >N?;6?????&?D?·?<br /> [ip] => 60.25.134.128<br /> [p] => 6881<br />)<br />Array<br />(<br /> [n] => >?e?l?????4?????<br /> [ip] => 81.224.44.195<br /> [p] => 56288<br />)<br />Array<br />(<br /> [n] => >?e?l?????4?????<br /> [ip] => 81.224.44.195<br /> [p] => 56288<br />)<br />Array<br />(<br /> [n] => >?e?l?????4?????<br /> [ip] => 81.224.44.195<br /> [p] => 56288<br />)<br />Array<br />(<br /> [n] => =¨?f%do????<br />3??–?<br /> [ip] => 223.166.253.13<br /> [p] => 6881<br />)<br />应该是没有问题的

PHP在現代Web開發中仍然重要,尤其在內容管理和電子商務平台。 1)PHP擁有豐富的生態系統和強大框架支持,如Laravel和Symfony。 2)性能優化可通過OPcache和Nginx實現。 3)PHP8.0引入JIT編譯器,提升性能。 4)雲原生應用通過Docker和Kubernetes部署,提高靈活性和可擴展性。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP在現代編程中仍然是一個強大且廣泛使用的工具,尤其在web開發領域。 1)PHP易用且與數據庫集成無縫,是許多開發者的首選。 2)它支持動態內容生成和麵向對象編程,適合快速創建和維護網站。 3)PHP的性能可以通過緩存和優化數據庫查詢來提升,其廣泛的社區和豐富生態系統使其在當今技術棧中仍具重要地位。

在PHP中,弱引用是通過WeakReference類實現的,不會阻止垃圾回收器回收對象。弱引用適用於緩存系統和事件監聽器等場景,需注意其不能保證對象存活,且垃圾回收可能延遲。

\_\_invoke方法允許對象像函數一樣被調用。 1.定義\_\_invoke方法使對象可被調用。 2.使用$obj(...)語法時,PHP會執行\_\_invoke方法。 3.適用於日誌記錄和計算器等場景,提高代碼靈活性和可讀性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)