PHP TCP服务端监听端口接收客户端RFID网络读卡器上传的读卡数据

本示例使用设备:WIFI/TCP/UDP/HTTP协议RFID液显网络读卡器可二次开发语音播报POE-淘宝网 (taobao.com)

<?php
header("content-type:text/html;charset=GBK");set_time_limit(0);
$port=39169;    //监听端口if(($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE){echo '初始化socket失败: ' . socket_strerror(socket_last_error($socket));exit;
}socket_set_nonblock($socket);// socket_bind(): 将socket资源绑定到指定地址
if(!socket_bind($socket, '0.0.0.0', $port)){echo '绑定端口失败: ' . socket_strerror(socket_last_error($socket));exit;
}// socket_listen(): 监听socket的连接请求
if(!socket_listen($socket)){echo '监听端口: ' . socket_strerror(socket_last_error($socket));exit;
}else{echo "TCP服务已启动,正在侦听端口:".$port."\n";}while(1){if(($client = socket_accept($socket)) !== FALSE){while(1){//这里不循环的话,只能接收到一次消息$content = socket_read($client, 10240);$content = trim($content);if($content){$response = AnalyzeData($content); //解析接收到的数据,并生成回应数据socket_write($client, $response);$Sendinf='';                    //将发送的信息用16进制数显示,方便调式for($i=0;$i<strlen($response);$i++){$byte = ord($response[$i]);$b=substr('00'.dechex($byte ),-2);$Sendinf=$Sendinf.$b.' ';}echo "发送数据:".$Sendinf."\n\n";}}}
}
socket_close($socket);//解析接收到的数据,并根据情况生成不同的回应数据
function AnalyzeData($inMsg)
{$len = strlen($inMsg);$bytes = array();$Getinf='';for($i=0;$i<$len;$i++){$byte = ord($inMsg[$i]);$bytes[] =  $byte ;$b=substr('00'.dechex($byte ),-2);$Getinf=$Getinf.$b.' ';}echo "接收数据:".$Getinf. PHP_EOL;switch($bytes[0]){case hexdec('0xF3'):        //接收到设备的心跳数据包,设备心跳间隔可根据协议自行设置$Ipaddstr=$bytes[1].".".$bytes[2].".".$bytes[3] .".".$bytes[4] ;$Machine=($bytes[5]+$bytes[6]*256) ;$frame=($bytes[7]+$bytes[8]*256) ;$Heartbeattype=substr('00'.dechex($bytes[9]),-2);$heartlen=$bytes[10];$switch=substr('00'.dechex($bytes[11]),-2);$keyinput=substr('00'.dechex($bytes[12]),-2);$Randcode=substr('00'.dechex($bytes[13]),-2).substr('00'.dechex($bytes[14]),-2).substr('00'.dechex($bytes[15]),-2).substr('00'.dechex($bytes[16]),-2);$SerialNum="";for($i=17;$i<sizeof($bytes);$i++){$SerialNum=$SerialNum.substr('00'.dechex($bytes[$i]),-2);}$Dispinf="数据解析:设备心跳包,设备IP:".$Ipaddstr.",机号:".$Machine.",数据包序号:".$frame.",心跳类型:".$Heartbeattype.",长度:".$heartlen.",继电器状态:".$switch.",按键值:".$keyinput.",随机码:".$Randcode.",硬件序列号:".$SerialNum;echo $Dispinf."\n\n";break;case hexdec('0xC1') or hexdec('0xCF') :     //接收IC读卡器上传的读卡号数据、IC卡离开读卡器的信息if($bytes[0]==hexdec('0xC1')){$Dispinf="数据解析:IC读卡器读取卡号,";}else{$Dispinf="数据解析:IC卡离开读卡器,";}$Ipaddstr=$bytes[1].".".$bytes[2].".".$bytes[3] .".".$bytes[4] ;$Machine=($bytes[5]+$bytes[6]*256) ;$frame=($bytes[7]+$bytes[8]*256) ;$Cardlen=$bytes[9];$Card16H="";for($i=0;$i<$Cardlen;$i++){$Card16H=$Card16H.substr('00'.dechex($bytes[10+$i]),-2);}$CardNo=$bytes[10] & 0xff;$CardNo=$CardNo+($bytes[11] & 0xff) *256;$CardNo=$CardNo+($bytes[12] & 0xff) *65536;$CardNo=$CardNo+($bytes[13] & 0xff) *16777216;$CardNo=substr("0000000000".$CardNo,-10);$SerialNum ="";for($i=10+$Cardlen;$i<$len;$i++){$SerialNum=$SerialNum.substr('00'.dechex($bytes[$i]),-2);}$Dispinf=$Dispinf."设备IP:".$Ipaddstr.",机号:".$Machine.",数据包序号:".$frame.",卡号长度:".$Cardlen.",16进制卡号:".$Card16H.",转十进制卡号:".$CardNo.",硬件序列号:".$SerialNum;echo $Dispinf."\n\n";//此处加入业务对数据库的查、增、删、减等操作$DispStr="卡号:".$CardNo."  ".substr(date('Y-m-d h:i:s', time()),0,16)."            "; //全屏显示信息长度>=34return GetResponseData(4,$DispStr); //生成回应数据break;case hexdec('0xD1') or hexdec('0xDF') :     //接收ID读卡器上传的读卡号数据、ID卡离开读卡器的信息if($bytes[0]==hexdec('0xD1')){$Dispinf="数据解析:ID读卡器读取卡号,";}else{$Dispinf="数据解析:ID卡离开读卡器,";}$Ipaddstr=$bytes[1].".".$bytes[2].".".$bytes[3] .".".$bytes[4] ;$Machine=($bytes[5]+$bytes[6]*256) ;$frame=($bytes[7]+$bytes[8]*256) ;$Card16H="";for($i=9;$i<14;$i++){$Card16H=$Card16H.substr('00'.dechex($bytes[10+$i]),-2);}$CardNo=$bytes[9] & 0xff;$CardNo=$CardNo+($bytes[10] & 0xff) *256;$CardNo=$CardNo+($bytes[11] & 0xff) *65536;$CardNo=$CardNo+($bytes[12] & 0xff) *16777216;$CardNo=substr("0000000000".$CardNo,-10);$SerialNum ="";for($i=14;$i<$len;$i++){$SerialNum=$SerialNum.substr('00'.dechex($bytes[$i]),-2);}$Dispinf=$Dispinf."设备IP:".$Ipaddstr.",机号:".$Machine.",数据包序号:".$frame.",16进制卡号:".$Card16H.",转十进制卡号:".$CardNo.",硬件序列号:".$SerialNum;echo $Dispinf."\n\n";//此处加入业务对数据库的查、增、删、减等操作$DispStr="卡号:".$CardNo."  ".substr(date('Y-m-d h:i:s', time()),0,16)."            "; //全屏显示信息长度>=34return GetResponseData(4,$DispStr); //生成回应数据break;default:}
}//根据情况生成不同的回应数据
function GetResponseData($respcode,$DispStr)
{$sdata = array();switch($respcode){case 0:     //回只应蜂鸣响声$sdata[0] = hexdec('0x96');    //指令码$sdata[1] = 0;                          //机号低位,$sdata[2] = 0;                          //机号高位,高低位都为0表示任意机号$sdata[3] = 1;                          //蜂鸣响声代码,取值范围0-12,代表12种不同的蜂鸣响声$sendBuf = '';for ($i = 0; $i < 4; $i++) {$sendBuf = $sendBuf . chr($sdata[$i]);}return $sendBuf;break;case 1:     //回应只开启继电器$sdata[0] = hexdec('0x78');    //指令码$sdata[1] = 0;                          //机号低位,$sdata[2] = 0;                          //机号高位,高低位都为0表示任意机号$sdata[3] = hexdec('0xF0');    //继电器代码 F0表示全部继电器、F1表示1号继电器 、F2表示2号继电器、F3表示3号继电器......$sdata[4] = hexdec('0x2C');    //继电器开启延时低位16进制$sdata[5] = hexdec('0x01');    //继电器开启延时高位16进制,高低位取值FFFF表示继电器一直开启$sendBuf = '';for ($i = 0; $i < 6; $i++) {$sendBuf = $sendBuf . chr($sdata[$i]);}return $sendBuf;break;case 2:     //回应只关闭已开启的继电器$sdata[0] = hexdec('0x78');    //指令码$sdata[1] = 0;                          //机号低位,$sdata[2] = 0;                          //机号高位,高低位都为0表示任意机号$sdata[3] = hexdec('0xE0');    //继电器代码 E0表示全部继电器、E1表示1号继电器 、E2表示2号继电器、E3表示3号继电器......$sdata[4] = hexdec('0x2C');    //继电器关闭延时低位16进制$sdata[5] = hexdec('0x01');    //继电器关闭延时高位16进制,高低位取值FFFF表示继电器一直关闭$sendBuf = '';for ($i = 0; $i < 6; $i++) {$sendBuf = $sendBuf . chr($sdata[$i]);}return $sendBuf;break;case 3:     //回应蜂鸣响声+文字显示$sdata[0]=hexdec('0x5A');    //指令码$sdata[1]=0;                          //机号低位$sdata[2]=0;                          //机号高位,高低位都为0表示任意机号$sdata[3]=2;                          //蜂鸣声代码,取值范围0-12,代表12种不同的蜂鸣响声$sdata[4]=20;                         //显示时长,单位秒,取值范围0-255,取值255时表示永久显示$sendBuf='';for($i=0;$i<5;$i++){$sendBuf=$sendBuf.chr($sdata[$i]);}$sendBuf=$sendBuf.$DispStr;return $sendBuf;break;case 4:     //回应蜂鸣响声+继电器开关+文字显示+播报TTS语音$SpeakStr="[v10]";                    //[v10]是语音大小,取值范围0-16,可加在任何地方,其他语音策略请看文档说明$SpeakStr=$SpeakStr."刷卡成功,感谢您使用我们的网络读卡器!";//要播报的TTS语音,每条指令最大不能超过126字符$Splen = strlen($SpeakStr);           //TTS语音长度//$sdata[0]=hexdec('0x5C');    //指令码$sdata[1]=0;                          //机号低位$sdata[2]=0;                          //机号高位,高低位都为0表示任意机号$sdata[3]=2;                          //蜂鸣声代码,取值范围0-12,代表12种不同的蜂鸣响声$sdata[4]=hexdec('0xF0');    //继电器代码 F0表示全部继电器 F1表示1号继电器 F2表示2号继电器$sdata[5]=hexdec('0x2C');    //继电器开启时长低位$sdata[6]=hexdec('0x01');    //继电器开启时长高位$sdata[7]=hexdec('0x14');    //显示保留时间,单位为秒,为0xFF时表示永久显示$sdata[8]=0;                          //在显示屏中的哪个位置开始$sdata[9]=hexdec('0x22');    //显示字符串长度 为全屏显示为 34 个字符$sdata[10]=$Splen;                    //语音长度$suffixStr=chr(hexdec('0x55')).chr(hexdec('0xaa')).chr(hexdec('0x66')).chr(hexdec('0x99'));  //固定的抗干扰后缀$sendBuf='';for($i=0;$i<11;$i++){$sendBuf=$sendBuf.chr($sdata[$i]);}$sendBuf=$sendBuf.substr($DispStr,0,34).$SpeakStr.$suffixStr;   //最长显示34个字符return $sendBuf;break;default:}
}//获取本机IP地址------------------------------------------------------------------------------------------------------------------------
function get_local_ip()
{$preg = "/\A((([0-9]?[0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))\.){3}(([0-9]?[0-9])|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))\Z/";//获取操作系统为win2000/xp、win7的本机IP真实地址$Netdriv=array();exec("ipconfig", $out, $stats);if (!empty($out)) {foreach ($out AS $row) {if (strstr($row, "IP") && strstr($row, ":") && !strstr($row, "IPv6")) {$tmpIp = explode(":", $row);if (preg_match($preg, trim($tmpIp[1]))) {$Netdriv[]=trim($tmpIp[1]);echo trim($tmpIp[1])."\n";}}}}//获取操作系统为linux类型的本机IP真实地址//exec("ifconfig", $out, $stats);//if (!empty($out)) {//    if (isset($out[1]) && strstr($out[1], 'addr:')) {//        $tmpArray = explode(":", $out[1]);//        $tmpIp = explode("", $tmpArray[1]);//        if (preg_match($preg, trim($tmpIp[0]))) {//            return trim($tmpIp[0]);//        }//    }//}if (!empty($Netdriv)) {return $Netdriv[0];   //如果有多张网块,可以修改数组取值来绑定相应的网卡}else{return '127.0.0.1';}
}?>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/175344.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

共享模型之不可变

前言 该文章后续还需要进行修改&#xff01;&#xff01; 不可变的解释是对象属性不可以更改。 在多线程下&#xff0c;格式转化使用SimpleDateFormat可能会报错。这是因为线程之间互相影响导致。 public class test {public static void main(String[] args) {SimpleDateFo…

抽象类-Java

抽象类 一、父类方法的不确定性二、抽象类介绍三、抽象类细节四、练习题 一、父类方法的不确定性 引入&#xff1a;对于一个动物&#xff0c;不知道它吃什么&#xff0c;比如猫吃鱼&#xff0c;兔子吃萝卜。动物类中的 eat 方法往往由它的子类去具体实现。 class Animal {pub…

qgis添加arcgis的FeatureServer

左侧浏览器-ArcGIS要素服务器-新建连接 http://sampleserver6.arcgisonline.com/arcgis/rest/services/ 展开-双击即可

sql中group by和having的使用

group by&#xff1a;按照某个字段或者某些字段进行分组。 having&#xff1a;对分组之后的数据进行再次过滤&#xff0c;having必须和group by一起用&#xff0c;且在group by后面。 比如person表如下&#xff08;以下查询均基于此表&#xff09;&#xff1a; 1.group by 用法…

为何要隐藏IP地址?网络上哪些行为需要隐藏IP和更换IP?

网络已经成为现代人生活的重要组成部分&#xff0c;人们在网络上交流、学习、娱乐、购物等。但是&#xff0c;在享受网络带来的便利时&#xff0c;我们也需要时刻保护自己的隐私和安全。其中&#xff0c;IP地址作为网络通信中的重要标识&#xff0c;如何隐藏以及在哪些情况下需…

C语言题目强化-DAY12

题型指引 一、选择题二、编程题 ★★写在前面★★ 本题库源自互联网&#xff0c;仅作为个人学习使用&#xff0c;记录C语言题目练习的过程&#xff0c;如果对你也有帮助&#xff0c;那就点个赞吧。 一、选择题 1、请阅读以下程序&#xff0c;其运行结果是&#xff08; &#x…

CMake语法解读 | Qt6需要用到

CMake 入门CMakeLists.txtmain.cpp编译示例cmake常用参数入门 Hello CMake CMake 是一个用于配置跨平台源代码项目应该如何配置的工具建立在给定的平台上。 ├── CMakeLists.txt # 希望运行的 CMake命令 ├── main.cpp # 带有main 的源文件 ├── include # 头文件目录 …

GLM: 自回归空白填充的多任务预训练语言模型

当前&#xff0c;ChatGLM-6B 在自然语言处理领域日益流行。其卓越的技术特点和强大的语言建模能力使其成为对话语言模型中的佼佼者。让我们深入了解 ChatGLM-6B 的技术特点&#xff0c;探索它在对话模型中的创新之处。 GLM: 自回归空白填充的多任务预训练语言模型 ChatGLM-6B 技…

C++二分查找视频教程:两数之和

作者推荐 利用广度优先或模拟解决米诺骨牌 本文涉及的基础知识点 二分查找算法合集 题目 给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 n…

Webhook端口中的自签名身份验证

概述 有时&#xff0c;可能需要通过 Webhook 端口从交易伙伴处接收数据&#xff0c;但该交易伙伴可能需要更多的安全性&#xff0c;而不仅仅是用于验证入站 Webhook 请求的基本身份验证用户名/密码 – 或者您可能只想在入站 Webhook 消息上添加额外的安全层。 使用 Webhook 端…

使用STM32和蓝牙模块进行无线数据传输的实践

无线数据传输在现代通信领域中具有重要的地位&#xff0c;而蓝牙技术是一种常用的无线数据传输技术。本文介绍了如何使用STM32微控制器和蓝牙模块实现无线数据传输的方案&#xff0c;包括硬件设计、蓝牙模块配置、数据发送和接收等步骤&#xff0c;并给出相应的代码示例。 一、…

Codebeamer—软件全生命周期管理轻量级平台

产品概述 Codebeamer涵盖了软件研发的生命周期&#xff0c;在一个整合的平台内支持需求管理、测试管理、软件开发过程管理以及项目管理等&#xff0c;同时具有IToperations&DevOps相关的内容&#xff0c;并支持变体管理的功能。对于使用集成的应用程序生命周期管理&#xf…

13.端点、簇、属性

源码地址&#xff1a;13.端点、簇、属性 端点&#xff08;endPoint&#xff09; 一个端点就是一个应用 一个字节编号&#xff0c;数据收和发送的基本单元&#xff0c;在模块通信的时候&#xff0c;发送模块必须指定收发双方模块的网络地址和端点。端点要使用必须要和模块里的…

MFC添加窗体菜单栏和消息响应

在资源视图右键,添加资源,选择Menu,新建 添加的菜单在资源菜单的Menu目录下 双击直接编辑输入菜单 之后在要添加菜单的窗体的属性Menu里面填写菜单的ID就可以了 如何给菜单添加点击响应? OnCommand是MFC中的一个消息处理函数,用于处理在窗口或控件被激活时发出的WM_CO…

java.sql.SQLException: No suitable driver 问题解决

问题出现 自己在写一个连接C3P0数据库连接池库的测试类&#xff0c;运行该类后出现了下图这个问题 这是我写的测试类 package demo;import com.mchange.v2.c3p0.ComboPooledDataSource;import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLExcept…

竞赛选题 题目:基于大数据的用户画像分析系统 数据分析 开题

文章目录 1 前言2 用户画像分析概述2.1 用户画像构建的相关技术2.2 标签体系2.3 标签优先级 3 实站 - 百货商场用户画像描述与价值分析3.1 数据格式3.2 数据预处理3.3 会员年龄构成3.4 订单占比 消费画像3.5 季度偏好画像3.6 会员用户画像与特征3.6.1 构建会员用户业务特征标签…

Unity Meta Quest 一体机开发(八):实现 Hand Grab 扔物体功能

文章目录 &#x1f4d5;教程说明&#x1f4d5;设置刚体和碰撞体&#x1f4d5;给物体添加 Physics Grabbable 脚本&#x1f4d5;给手部添加 Hand Velocity Calculator 物体 此教程相关的详细教案&#xff0c;文档&#xff0c;思维导图和工程文件会放入 Seed XR 社区。这是一个高…

Open Feign 源码解析(一) --- FactoryBean的妙用

什么是Open Feign? OpenFeign 是 Spring Cloud 全家桶的组件之一&#xff0c; 其核心的作用是为 Rest API 提供高效简洁的 RPC 调用方式 搭建测试项目 服务接口和实体 项目名称 cloud-feign-api 实体类 public class Order implements Serializable {private Long id;p…

Vue3的项目创建到启动

Vue3的项目创建 检查node版本创建 npm init vuelatest 安装依赖 项目启动 启动成功

java学习part15单例模式

107-面向对象(高级)-单例设计模式与main()的理解_哔哩哔哩_bilibili 1.单例 就是说在某些开发场景中&#xff0c;某个类只要有一个对象就足够使用了&#xff0c;不需要重复创建。 &#xff08;理解&#xff1a;比如说是数据库对象&#xff0c;使用时创建一个可以处理所有的数…