门禁UDP协议-demo1-xt
swoole 2018-06-13 13:30:58

1、模拟发送UDP包

发送十六进制的数据包:

 

PHP Code复制内容到剪贴板
  1. <?php  
  2. /** 
  3.  * Created by PhpStorm. 
  4.  * User: yoyo 
  5.  * Date: 2018/5/9 
  6.  * Time: 下午19:19 
  7.  */  
  8. function getSendData(array $headarray $body = array())  
  9. {  
  10.     $length = count($body); // 包体长度  
  11.     $hight = ($length & 0xff00) >> 8; // 高位右移8个位  
  12.     $low = $length & 0x00ff; // 低位  
  13.   
  14.     // ********模拟发送的时候,高低位颠倒  
  15.     $head[] = $hight;     // 数据长度低位  
  16.     $head[] = $low;   // 数据长度高位  
  17.   
  18.     // 正常解析  
  19. //    $head[] = $low;     // 数据长度低位  
  20. //    $head[] = $hight;   // 数据长度高位  
  21.   
  22.     // 将包头和包体 合并  
  23.     $data = $body ? array_merge_recursive($head$body) : $head;  
  24.   
  25.     $check = getCheckVal($data); // 获取校验值  
  26.     $data[] = $check;  
  27.     $data[] = "03";  
  28.     return get_pack($data);  
  29. }  
  30.   
  31. /** 
  32.  * 根据数组中所有值 获取校验值 
  33.  * @param array $data 
  34.  * @return float|int|string 
  35.  */  
  36. function getCheckVal(array $data)  
  37. {  
  38.     // 将第一个放进循环中会报错,单独将第一个字节先取出来  
  39.     $check = hexdec("0x" . $data[0]);  
  40.     // 所有数据 进行异或运算,从数组中的第二个开始 (测试数据,减掉包尾)  
  41.     $i = 0;  
  42.   
  43.     // 这里的data是十六进制的字符串,要先将它以0x组合出来16进制的字符串,再转换为10进制的数字用以运算  
  44.     // 得到的结果是十进制的校验值  
  45.     foreach ($data as $d) {  
  46.         $i++;  
  47. //            echo "打印加入运算的字符:" . $d.PHP_EOL;  
  48.         if ($i == 1) {  
  49.             $check = $d;  
  50.         } else {  
  51.             $check ^= $d;  
  52.         }  
  53.     }  
  54.     //    $check = dechex($check); // 结果:是十进制的,最后,将十进制转十六进制字符,这里不需要转换十六进制,因为最后还需要将数据放到pack方法中转换  
  55.     return $check;  
  56. }  
  57.   
  58. function get_pack($data)  
  59. {  
  60.     $pack = "";  
  61.     foreach ($data as $k => $d) {  
  62.         $pack .= pack("C*"$d); // 十六进制应答  
  63.     }  
  64.     echo "十六进制转为字符串应答的数据:" . bin2hex($pack) . PHP_EOL;  
  65.     return $pack;  
  66. }  
  67.   
  68.   
  69. $client = new swoole_client(SWOOLE_SOCK_UDP);  
  70. $client->connect('0.0.0.0', 9300, 1);  
  71.   
  72. /** 
  73.  * 自己组合数据发送 
  74.  */  
  75. //$num = rand(0, 100); // 随机数(保留)  
  76. //$address = "164"; // 控制器地址(保留)  
  77. //$door = 1; // 门编号  
  78. //$command = 56; //状态  
  79. //// 包头  
  80. //$pack_head = [  
  81. //    "02",  
  82. //    $num,  
  83. //    $command,  
  84. //    $address,  
  85. //    $door,  
  86. //];  
  87. //// 包体  
  88. //$pack_body = [  
  89. //    $command  
  90. //];  
  91. //$sendData = getSendData($pack_head, $pack_body);  
  92.   
  93.   
  94. /** 
  95.  * 
  96.  */  
  97. $str = "02aa560000001d0012060c12082003120039010000000000005a000031463731363448038a03";  
  98. $receiveStr = str_replace(' '''$str); // *********************************测试时开放,直接传十六进制字符串,可以有空格,会直接替换掉  
  99.   
  100. //    $receiveStr = bin2hex($data); // 将2进制数据转换成16进制的字符串,就是文档中的原数据了  
  101. $length = strlen($receiveStr); // 计算十六进制字符串长度  
  102. if ($length % 2 == 0) {  
  103.     // 必须没有余数  
  104.     $length = $length / 2; // 每两位分割为一个数组  
  105.     $arr = [];  
  106.     for ($i = 0; $i < $length$i++) {  
  107.         $str = hexdec("0x" . substr($receiveStr$i * 2, 2));  
  108.         array_push($arr$str);  
  109.     }  
  110.     $sendData = get_pack($arr);  
  111. }  
  112.   
  113.   
  114. $client->send($sendData);  
  115. $message = $client->recv();  
  116. echo "Get Message From Server:{$message}\n";  

 

本文来自于:http://www.yoyo88.cn/study/swoole/315.html

上一篇 高低位算法
下一篇 同步mysql
Powered by yoyo苏ICP备15045725号