门禁UDP协议-demo1-xt
1、模拟发送UDP包
发送十六进制的数据包:
PHP Code复制内容到剪贴板
- <?php
- /**
- * Created by PhpStorm.
- * User: yoyo
- * Date: 2018/5/9
- * Time: 下午19:19
- */
- function getSendData(array $head, array $body = array())
- {
- $length = count($body); // 包体长度
- $hight = ($length & 0xff00) >> 8; // 高位右移8个位
- $low = $length & 0x00ff; // 低位
- // ********模拟发送的时候,高低位颠倒
- $head[] = $hight; // 数据长度低位
- $head[] = $low; // 数据长度高位
- // 正常解析
- // $head[] = $low; // 数据长度低位
- // $head[] = $hight; // 数据长度高位
- // 将包头和包体 合并
- $data = $body ? array_merge_recursive($head, $body) : $head;
- $check = getCheckVal($data); // 获取校验值
- $data[] = $check;
- $data[] = "03";
- return get_pack($data);
- }
- /**
- * 根据数组中所有值 获取校验值
- * @param array $data
- * @return float|int|string
- */
- function getCheckVal(array $data)
- {
- // 将第一个放进循环中会报错,单独将第一个字节先取出来
- $check = hexdec("0x" . $data[0]);
- // 所有数据 进行异或运算,从数组中的第二个开始 (测试数据,减掉包尾)
- $i = 0;
- // 这里的data是十六进制的字符串,要先将它以0x组合出来16进制的字符串,再转换为10进制的数字用以运算
- // 得到的结果是十进制的校验值
- foreach ($data as $d) {
- $i++;
- // echo "打印加入运算的字符:" . $d.PHP_EOL;
- if ($i == 1) {
- $check = $d;
- } else {
- $check ^= $d;
- }
- }
- // $check = dechex($check); // 结果:是十进制的,最后,将十进制转十六进制字符,这里不需要转换十六进制,因为最后还需要将数据放到pack方法中转换
- return $check;
- }
- function get_pack($data)
- {
- $pack = "";
- foreach ($data as $k => $d) {
- $pack .= pack("C*", $d); // 十六进制应答
- }
- echo "十六进制转为字符串应答的数据:" . bin2hex($pack) . PHP_EOL;
- return $pack;
- }
- $client = new swoole_client(SWOOLE_SOCK_UDP);
- $client->connect('0.0.0.0', 9300, 1);
- /**
- * 自己组合数据发送
- */
- //$num = rand(0, 100); // 随机数(保留)
- //$address = "164"; // 控制器地址(保留)
- //$door = 1; // 门编号
- //$command = 56; //状态
- //// 包头
- //$pack_head = [
- // "02",
- // $num,
- // $command,
- // $address,
- // $door,
- //];
- //// 包体
- //$pack_body = [
- // $command
- //];
- //$sendData = getSendData($pack_head, $pack_body);
- /**
- *
- */
- $str = "02aa560000001d0012060c12082003120039010000000000005a000031463731363448038a03";
- $receiveStr = str_replace(' ', '', $str); // *********************************测试时开放,直接传十六进制字符串,可以有空格,会直接替换掉
- // $receiveStr = bin2hex($data); // 将2进制数据转换成16进制的字符串,就是文档中的原数据了
- $length = strlen($receiveStr); // 计算十六进制字符串长度
- if ($length % 2 == 0) {
- // 必须没有余数
- $length = $length / 2; // 每两位分割为一个数组
- $arr = [];
- for ($i = 0; $i < $length; $i++) {
- $str = hexdec("0x" . substr($receiveStr, $i * 2, 2));
- array_push($arr, $str);
- }
- $sendData = get_pack($arr);
- }
- $client->send($sendData);
- $message = $client->recv();
- echo "Get Message From Server:{$message}\n";