首页
谈天说地
友情链接
统计
Search
1
composer国内常用镜像
50 阅读
2
分享一个在laravel中打印执行的sql语句的函数
45 阅读
3
workerman自定义协议-----modbus-rtu协议
22 阅读
猿来如此
资源推荐
其它
Search
标签搜索
php
composer
laravel
sql
workerman
modbus
M17
累计撰写
3
篇文章
累计收到
0
条评论
首页
栏目
猿来如此
资源推荐
其它
页面
谈天说地
友情链接
统计
搜索到
1
篇与
workerman
相关的结果
2023-06-08
workerman自定义协议-----modbus-rtu协议
{callout color="#000000"}这是一个简易版的modbus-rtu协议处理的实现,可根据需求自行修改{/callout}{lamp/}<?php namespace app\library; use Workerman\Connection\ConnectionInterface; /** * 自定义modbus-rtu协议 * 正常应答格式:地址码(1字节) + 功能码(1字节) + 数据(0-252字节) + crc校验码(2字节) * 功能码取值范围:1-127 * 异常应答格式:地址码(1字节) + 异常功能码(1字节) + 异常码(1字节) + crc校验码(2字节) * 异常功能码 = 正常功能码+0x80 取值范围:129(1+128)- 255(127+128) * 异常码:01,02,03,04,05,06,07,08,0A,0B */ class ModbusRtuProtocol { // 常用功能码 const READ_COILS = 1; const READ_INPUT_DISCRETES = 2; const READ_HOLDING_REGISTERS = 3; const READ_INPUT_REGISTERS = 4; const WRITE_SINGLE_COIL = 5; const WRITE_SINGLE_REGISTER = 6; const WRITE_MULTIPLE_COILS = 15; const WRITE_MULTIPLE_REGISTERS = 16; const MASK_WRITE_REGISTER = 22; const READ_WRITE_MULTIPLE_REGISTERS = 23; // 异常码增量 const EXCEPTION_BITMASK = 128; // 附加数据长度 protected static $extraData = [ 'imei' => 10, 'ping' => 4 ]; /** * 检查包的完整性 * * 如果可以在$recv_buffer中得到请求包的长度则返回整个包的长度 * 否则返回0,表示需要更多的数据才能得到当前请求包的长度 * 如果返回false或者负数,则代表错误的请求,则连接会断开 * * @param string $recv_buffer * @param ConnectionInterface $connection * * @return int */ public static function input($buffer, ConnectionInterface $connection) { $recv_len = strlen($buffer); // 少于4个字节则返回0,继续等待数据 if ($recv_len < 4) { return 0; } // 是否包含二进制字符 if (preg_match('~[^\x20-\x7E\t\r\n]~', $buffer) > 0) {} // 以开始4字节字符判断 $args = self::$extraData; $ascTag = substr($buffer, 0, 4); if (isset($args[$ascTag])) { $frame_length = $args[$ascTag]; } else { try { $isCompare = self::isCompleteLengthRTU($buffer); // 长度不够继续等待 if ($isCompare === false) { return 0; } $frame_length = $recv_len; } catch (\Throwable $th) { // 断开连接 $connection->close(); return 0; } } // 如果缓冲区的长度小于数据帧的长度,则返回0,继续等待数据 if ($recv_len < $frame_length) { return 0; } return $frame_length; } /** * 用于请求解包 * * input返回值大于0,并且WorkerMan收到了足够的数据,则自动调用decode * 然后触发onMessage回调,并将decode解码后的数据传递给onMessage回调的第二个参数 * 也就是说当收到完整的客户端请求时,会自动调用decode解码,无需业务代码中手动调用 * @param ConnectionInterface $connection * @param string $recv_buffer */ public static function decode($buffer) { $relation = self::$extraData; $tagstr = substr($buffer, 0, 4); // 返回字符串 // if (isset($relation[$tagstr])) { // return $buffer; // } // return bin2hex($buffer); // 返回数组 $type = 'report'; $data = bin2hex($buffer); if (isset($relation[$tagstr])) { $type = $tagstr; $data = $buffer; } return compact('type', 'data'); } /** * 用于请求打包 * * 当需要向客户端发送数据即调用$connection->send($data);时 * 会自动把$data用encode打包一次,变成符合协议的数据格式,然后再发送给客户端 * 也就是说发送给客户端的数据会自动encode打包,无需业务代码中手动调用 * @param ConnectionInterface $connection * @param mixed $data */ public static function encode($buffer) { // TEST TODO... $buffer = str_replace(' ', '', $buffer); if (!ctype_xdigit($buffer)) $buffer = bin2hex($buffer); return hex2bin($buffer); } /** * 检测是否完整rtu格式数据包 * * @param [type] $binaryData * @return boolean */ public static function isCompleteLengthRTU($binaryData) { // 最小RTU数据包长度为5字节(1字节地址+1字节功能码+1字节错误码或1字节长度+2字节CRC) $length = strlen($binaryData); if ($length < 5) { return false; } // 功能码 $functionCode = ord($binaryData[1]); // 异常响应 if ($functionCode - self::EXCEPTION_BITMASK > 0) { return true; } switch ($functionCode) { case self::READ_COILS: case self::READ_INPUT_DISCRETES: case self::READ_HOLDING_REGISTERS: case self::READ_INPUT_REGISTERS: case self::READ_WRITE_MULTIPLE_REGISTERS: $responseBytesLen = 3 + ord($binaryData[2]); break; case self::WRITE_SINGLE_COIL: case self::WRITE_SINGLE_REGISTER: case self::WRITE_MULTIPLE_COILS: case self::WRITE_MULTIPLE_REGISTERS: $responseBytesLen = 6; break; case self::MASK_WRITE_REGISTER: $responseBytesLen = 8; break; default: throw new \Exception("can not determine complete length for unsupported modbus function code"); } // 加上2位crc校验码 $expectedLength = $responseBytesLen + 2; if ($length > $expectedLength) { throw new \Exception("packet length more bytes than expected"); } return $length === $expectedLength; } }
2023年06月08日
22 阅读
0 评论
0 点赞