本文介绍: PHP 开发的TCP Server 端口监听,获取RFID网络读卡器上传的卡号、机号,回应驱动读卡器显示文字、蜂鸣响声、开启继电器开关、播报TTS中文语音

示例使用设备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."nn";
            }
        }
    }
}
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."nn";
            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] &amp; 0xff;
            $CardNo=$CardNo+($bytes[11] &amp; 0xff) *256;
            $CardNo=$CardNo+($bytes[12] &amp; 0xff) *65536;
            $CardNo=$CardNo+($bytes[13] &amp; 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."nn";

            //此处加入业务对数据库的查、增、删、减等操作

            $DispStr="卡号:".$CardNo."  ".substr(date('Y-m-d h:i:s', time()),0,16)."            "; //全屏显示信息长度&gt;=34
            return 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] &amp; 0xff;
            $CardNo=$CardNo+($bytes[10] &amp; 0xff) *256;
            $CardNo=$CardNo+($bytes[11] &amp; 0xff) *65536;
            $CardNo=$CardNo+($bytes[12] &amp; 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."nn";

            //此处加入业务对数据库的查、增、删、减等操作

            $DispStr="卡号:".$CardNo."  ".substr(date('Y-m-d h:i:s', time()),0,16)."            "; //全屏显示信息长度&gt;=34
            return 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';
    }
}

?>

 

原文地址:https://blog.csdn.net/zhangjin7422/article/details/134640044

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_2199.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注