ホームページ >バックエンド開発 >PHPチュートリアル >php のソケット問題について専門家がやって来ます!

php のソケット問題について専門家がやって来ます!

WBOY
WBOYオリジナル
2016-06-23 13:36:21842ブラウズ

ハードウェアがサーバー ポートにデータを送信します (パケット キャプチャ ソフトウェアは正しい 16 進数を取得します)。パケット キャプチャ ソフトウェアを通じてキャプチャされたデータは通常 (16 進数) ですが、PHP ソケットを通じて受信されたデータは (変換後は 16 進数になります)。 16 進数のままであり、変換されていない場合は文字化けします)。専門家が問題を解決できるようにしてください。 PHP ソケットで取得したデータとパケット キャプチャ ソフトウェアで取得したデータが異なるのはなぜですか? php 経由 ソケットによって取得されたデータ (dechex()、ord() を通じて変換され、ソフトウェアがキャプチャしたものとは異なり、間違っています): fa 7 25 2 fa 2 0 9 f6 4 2c 88 fa 1

Paste php以下ソケットコード:

<?phperror_reporting(E_ALL);set_time_limit(0);ini_set("allow_call_time_pass_reference",true);//监听端口$PORT = 8888;//最大连接池$MAX_USERS = 50000;//创建监听端口//$sock = socket_create_listen($PORT);$commonProtocol = getprotobyname("tcp");$sock = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);@socket_bind($sock, '192.168.1.101', 8888);@socket_listen($sock);if (!$sock){    exit(1);}//不阻塞socket_set_nonblock($sock);$connections = array();$input = array();$close = array();while (true){	//sleep(3);    $readfds = array_merge($connections, array($sock));    $writefds = array();    //选择一个连接,获取读、写连接通道    if (socket_select($readfds, $writefds, $e = null, $t=60))    {        foreach ($readfds as $rfd)        {            //如果是当前服务端的监听连接            if ($rfd == $sock)            {                //接受客户端连接                $newconn = socket_accept($sock);                $i = (int)$newconn;                $reject = '';                if (count($connections) >= $MAX_USERS)                {                    $reject = "Server full. Try again later.\n";                                   }                                //将当前客户端连接放如socket_select选择                $connections[$i] = $newconn;                //输入的连接资源缓存容器                $writefds[$i] = $newconn;                               //连接不正常                if ($reject)                {                                      $close[$i] = true;                }                else                {                    echo "Welcome to the PHP Chat Server!\n";                                  }                               //初始化当前连接读取内容的缓存容器                $input[$i] = "";                continue;            }            //客户端连接            $i = (int)$rfd;            //读取            $tmp = @socket_read($rfd, 14, PHP_NORMAL_READ);            if (!$tmp)            {                //读取不到内容                              print "connection closed on socket $i\n";                close($i);                continue;            }            $input[$i] .= $tmp;            $tmp = substr($input[$i], -1);            /*if ($tmp != "\r" && $tmp != "\n")            {                // no end of line, more data coming                continue;            }*/            $line = trim($input[$i]);            $input[$i] = "";            echo 'Client >>'.$line."\r\n";												$data=str_split($line);  print_r($data); echo "\r\n";						//$data = explode("\t",$line);			//$data=str_split($data);			foreach($data as $v){			 echo dechex(ord($v))."\t";			 			 }			 echo "\r\n";															socket_getpeername($connections[$i],&$remoteIP,&$remotePort);echo $remoteIP."\r\n";echo $remotePort."\r\n";//$data=str_split($buffer);//print_r($data);$str="\xFA\x01\x01\xFF\xAA\xAA\x00\x01\x00\x00\x00\x00\x00\x01"; socket_send($connections[$i],$str,strlen($str),0);																		        }        foreach ($writefds as $wfd)        {            $i = (int)$wfd;            $w = socket_write($wfd, "hello");        }    }   }function close($i){    global $connections, $input, $close;    socket_shutdown($connections[$i]);    socket_close($connections[$i]);    unset($connections[$i]);    unset($input[$i]);       unset($close[$i]);}?>



ディスカッションに返信 (解決策)
シーンとコードを完全にシミュレート

$str="\xFA\x01\x01\xFF\xAA\xAA\x00\x01\x00\x00\x00\x00\x00\x01";$line = $str;$data = str_split($line);foreach($data as $v){  echo dechex(ord($v))."\t";}

fa 1 1 ff aa aa 0 1 0 0 0 0 0 1


Didn't違いは何ですか


サイトとコードを完全にシミュレートします

PHP コード


$str="xFAx01x01xFFxAAx00x01x00x00x00x00x00x01";

$line = $str
$data = str_split ( $line);
foreach($data) as $ v){
echo dechex(ord($v))."t";
}

Get
f...


シミュレートしたデータはハードウェアに送信されます。私の要件は次のとおりです。送信したデータをソケットで受信すると異常でした。パケットキャプチャツールで取得したデータは正しいのですが(FA 01 01 FF AA 03 00 01 00 0B 00 00 00 A3)、ソケットで取得したデータは正しくありませんでした。 DOS で文字化けしました (ord (取得したデータ)): fa 7 25 2 fa 2 0 9 f6 4 2c 88 fa 1 (間違っています)、取得したいのはパケット キャプチャ ツールと同じデータです。 (例: FA 01 01 FF AA 03 00 01 00 0B 00 00 00 A3)


$line = trim($input[$i]); これは受信したデータですか?
1. トリムを削除します。そうしないと、受信データが切り捨てられる可能性があります 2. バイナリデータであるため、結果を echobase64_encode($input[$i]); します





$line = trim( $ input[$i]); これは受信したデータですか?

1. トリムを削除します。そうしないと、受信データが切り捨てられる可能性があります

2. バイナリデータであるため、結果を echobase64_encode($input[$i]); します



+gclAvoCAAn2BCyI+gEB+v/6AQH / qqoAAQAAAAAAAfoBAf+qqgABAAAA
これが受信データです

$s = base64_decode('+gclAvoCAAn2BCyI+gEB+v/6AQH/qqoAAQAAAAAAAfoBAf+qqgABAAAA');print_r(unpack('H*', $s));//或for($i=0; $i<strlen($s); $i++) printf(' %02X', ord($s{$i}));

$line = trim($input[$i]); これが受信データですか?

1. トリムを削除します。そうしないと、受信データが切り捨てられる可能性があります

2. バイナリデータであるため、結果を echobase64_encode($input[$i]); します


下の画像は、パケット キャプチャ ツールによってキャプチャされたデータです(正しいデータ)、図の斜線部分の 16 進数データを矢印のデータに変換する方法、およびそれを 16 進数に戻す方法

[img=http://bbs.php100. /Mon_1208/18_219521_355456b7c8c862b.jpg?93][/img]

受け取ったのはバイナリ データですが、なぜそれを転送したいのですか?
赤線で囲ったものは、データの 16 進数表現です。

1 バイトは 8 つの 2 進数であり、1 つの 16 進数は 4 つの 2 進数です。
2 つの 16 進数は 1 バイトの内容を正確に表します。


phpソケットを使用して現在受信しているデータは、矢印で示されている(変数$aに配置されている)データです。今度は、それを図の円の影付きの部分のデータに変換したいと思います。 、16進数)、変換するにはどうすればよいですか?

受け取ったものはバイナリ データですが、なぜそれを転送したいのですか?

赤線で囲ったものは、データの 16 進数表現です。

1 バイトは 8 つの 2 進数であり、1 つの 16 進数は 4 つの 2 進数です。
2 つの 16 進数は 1 バイトの内容を正確に表します。


phpソケットを使用して現在受信しているデータは、矢印で示されている(変数$aに配置されている)データです。今度は、それを図の円の影付きの部分のデータに変換したいと思います。 、16進数)、変換するにはどうすればよいですか?


私 #6 があなたにコードを渡しましたよね?
私が言うと少し混乱して聞こえるかもしれません、ごめんなさい

是否有转义符?

我 #6 不是给你代码了吗?



现在的确是可以获取到代码了,但是少了3个16进制的数据

获取到的代码是:fa072502fa020009f6042c88fa0101fafffa0101ffaa030001000b00

抓包得到的是:FA 01 01 FF AA 03 00 01 00 0B 00 00 00 A3

也就是少了 00 00 A3

<?php        $sendStr = '30 32 30 34 03 30 33';  // 16进制数据        $sendStrArray = str_split(str_replace(' ', '', $sendStr), 2);  // 将16进制数据转换成两个一组的数组        $socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname("tcp"));  // 创建Socket        if (socket_connect($socket, "192.168.1.100", 8080)) {  //连接            for ($j = 0; $j < count($sendStrArray); $j++) {                socket_write($socket, chr(hexdec($sendStrArray[$j])));  // 逐组数据发送            }            $receiveStr = "";            $receiveStr = socket_read($socket, 1024, PHP_BINARY_READ);  // 采用2进制方式接收数据            $receiveStrHex = bin2hex($receiveStr);  // 将2进制数据转换成16进制            echo "client:" . $receiveStrHex;        }        socket_close($socket);  // 关闭Socket        ?>

可以完美解决你的问题。。。。。。刚看见这个你的问题

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:SQLクエリの問題次の記事:SQLクエリの問題