Maison >développement back-end >tutoriel php >高手来,关于php中socket的问题!
一个硬件往服务器端口上发送数据(抓包软得到的是正确的16进制),通过抓包软件抓取的数据是正常的(16进制),然而通过php的socket接受到的数据(通过转换后也是16进制,未转换是乱码),下面贴上代码,请高手帮忙看下哪里错了。为什么php的socket获取的数据和抓包软件获取的不一样
通过抓包软件获取的正确代码是(16进制的):FA 01 01 FF AA 03 00 01 00 0B 00 00 00 A3
通过php socket获得的数据(通过dechex(),ord()转换后的,和软件抓取的不一样,是错误的):fa 7 25 2 fa 2 0 9 f6 4 2c 88 fa 1
下面贴上php的socket代码:
<?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";}得到
完全模拟你的现场和代码
PHP code
$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";
}
得到
f……
你有 $line = trim($input[$i]); 这是接受到的数据吧?
1、去掉 trim,否则传入的数据可能会被截断
2、因为是二进制数据,你 echo base64_encode($input[$i]); 贴出结果
你有 $line = trim($input[$i]); 这是接受到的数据吧?
1、去掉 trim,否则传入的数据可能会被截断
2、因为是二进制数据,你 echo base64_encode($input[$i]); 贴出结果
$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、去掉 trim,否则传入的数据可能会被截断
2、因为是二进制数据,你 echo base64_encode($input[$i]); 贴出结果
你收到的就是二进制数据,要转来转去干什么?
你红线框住的那些,是数据的十六进制表示。
一个字节是8个二进制位,1个十六进制数是4个二进制位
2个十六进制数正好表示一个字节的内容。
我现在用php socket收到的数据是箭头所指的数据(并且放在变量$a中),我现在想将她转换成图中圈中阴影部分的数据(也就是16进制),改如何转换呢?
你收到的就是二进制数据,要转来转去干什么?
你红线框住的那些,是数据的十六进制表示。
一个字节是8个二进制位,1个十六进制数是4个二进制位
2个十六进制数正好表示一个字节的内容。
我 #6 不是给你代码了吗?
说的感觉有点乱,不好意思
是否有转义符?
我 #6 不是给你代码了吗?
<?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 ?>