高手来,关于php中socket的问题!

cnaaa8 2012-08-13 04:27:37
一个硬件往服务器端口上发送数据(抓包软得到的是正确的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代码:

<?php
error_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]);
}
?>
...全文
361 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
shangbolei 2015-04-17
  • 打赏
  • 举报
回复
<?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
        ?>
可以完美解决你的问题。。。。。。刚看见这个你的问题
cnaaa8 2012-08-15
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]
我 #6 不是给你代码了吗?
[/Quote]

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

获取到的代码是:fa072502fa020009f6042c88fa0101fafffa0101ffaa030001000b00

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

也就是少了 00 00 A3

sddffd1223 2012-08-15
  • 打赏
  • 举报
回复
是否有转义符?
tanshikao 2012-08-15
  • 打赏
  • 举报
回复
说的感觉有点乱,不好意思
xuzuning 2012-08-14
  • 打赏
  • 举报
回复
你有 $line = trim($input[$i]); 这是接受到的数据吧?
1、去掉 trim,否则传入的数据可能会被截断
2、因为是二进制数据,你 echo base64_encode($input[$i]); 贴出结果

cnaaa8 2012-08-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
完全模拟你的现场和代码

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……
[/Quote]

你这个模拟的是发给硬件的数据是正常的,我的需求是:硬件发的数据我用socket接受不正常,通过抓包工具得到的数据是正确的(FA 01 01 FF AA 03 00 01 00 0B 00 00 00 A3),而用socket得到的数据,在dos下是乱码,我通过dechex(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)
xuzuning 2012-08-14
  • 打赏
  • 举报
回复
我 #6 不是给你代码了吗?
cnaaa8 2012-08-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
你收到的就是二进制数据,要转来转去干什么?

你红线框住的那些,是数据的十六进制表示。
一个字节是8个二进制位,1个十六进制数是4个二进制位
2个十六进制数正好表示一个字节的内容。
[/Quote]

我现在用php socket收到的数据是箭头所指的数据(并且放在变量$a中),我现在想将她转换成图中圈中阴影部分的数据(也就是16进制),改如何转换呢?
cnaaa8 2012-08-14
  • 打赏
  • 举报
回复
我现在用php socket收到的数据是箭头所指的数据(并且放在变量$a中),我现在想将她转换成图中圈中阴影部分的数据(也就是16进制),改如何转换呢?
xuzuning 2012-08-14
  • 打赏
  • 举报
回复
你收到的就是二进制数据,要转来转去干什么?

你红线框住的那些,是数据的十六进制表示。
一个字节是8个二进制位,1个十六进制数是4个二进制位
2个十六进制数正好表示一个字节的内容。
cnaaa8 2012-08-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
你有 $line = trim($input[$i]); 这是接受到的数据吧?
1、去掉 trim,否则传入的数据可能会被截断
2、因为是二进制数据,你 echo base64_encode($input[$i]); 贴出结果
[/Quote]
下图是通过抓包工具抓取的数据(正确的数据),图中圈住阴影部分的16进制的数据如何转换成箭头所指的数据,以及如何再转回到16进制

xuzuning 2012-08-14
  • 打赏
  • 举报
回复
$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}));
cnaaa8 2012-08-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
你有 $line = trim($input[$i]); 这是接受到的数据吧?
1、去掉 trim,否则传入的数据可能会被截断
2、因为是二进制数据,你 echo base64_encode($input[$i]); 贴出结果
[/Quote]


+gclAvoCAAn2BCyI+gEB+v/6AQH/qqoAAQAAAAAAAfoBAf+qqgABAAAA
这是得到的数据
xuzuning 2012-08-13
  • 打赏
  • 举报
回复
完全模拟你的现场和代码
$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

没看出有什么差别

20,359

社区成员

发帖
与我相关
我的任务
社区描述
“超文本预处理器”,是在服务器端执行的脚本语言,尤其适用于Web开发并可嵌入HTML中。PHP语法利用了C、Java和Perl,该语言的主要目标是允许web开发人员快速编写动态网页。
phpphpstorm 技术论坛(原bbs)
社区管理员
  • 开源资源社区
  • phpstory
  • xuzuning
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧