本示例使用设备: 实时网络双门双向门禁控制板可二次编程控制网络继电器远程开关-淘宝网 (taobao.com)
<?PHP
header("content-type:text/html;charset=GBK");
$ThisIp=get_local_ip(); //获取电脑IP地址
$server = 'udp://'.$ThisIp.':39192';
$socket = stream_socket_server($server, $errno, $errstr, STREAM_SERVER_BIND);
if (!$socket)
{
die("$errstr ($errno)");
}
echo "系统绑定的IP :".$ThisIp.":39192\n";
$LastFramesStr= ""; //保存最后接收到的信息,用于比较是否重复接收的信息
do{
//监听UDP端口,并将接收到的信息显示,正式项目只解析数据不需要显示
$inMsg = stream_socket_recvfrom($socket, 1024, 0, $peer);
$Fields = explode(",",$inMsg ); //将接收到的信息 分字段解析
echo "From Ip:".$peer."\n";
echo "Getdata:".$inMsg."\n\n" ;
switch($Fields[0]){
case "100": //*设备接收到000搜索指令后返回的设备信息*/
if(sizeof($Fields)<9){
$DevBufferIpAddrStr= $Fields[1]; /*终端IP*/
$DevBufferMaskStr= $Fields[2]; /*掩码*/
$DevBufferGatewayStr= $Fields[3]; /*网关*/
$DevBufferRemoteAddrStr= $Fields[4]; /*远程服务器IP*/
$DevBufferPort= $Fields[5]; /*端口*/
$DevBufferNumberDecStr= $Fields[6]; /*设备序号*/
}else{
$DevBufferIpAddrStr= $Fields[1]; /*终端IP*/
$DevBufferMaskStr= $Fields[2]; /*掩码*/
$DevBufferGatewayStr= $Fields[3]; /*网关*/
$DevBufferGatewayStrMAC= $Fields[4]; /*网关MAC*/
$DevBufferRemoteAddrStr= $Fields[5]; /*远程服务器IP*/
$DevBufferRemoteAddrMACStr= $Fields[6]; /*远程服务器IPMAC*/
$DevBufferMACSearchStr= $Fields[7]; /*MAC搜索标识*/
$DevBufferPort= $Fields[8]; /*端口*/
$DevBufferNumberDecStr= $Fields[9]; /*设备模块序号*/
if(strArr.length>10){
$DevBufferSerialNumStr= $Fields[10]; /*设备唯一硬件序号*/
}
if(strcmp($DevBufferRemoteAddrStr,"255.255.255.255")!=0 && strcmp($DevBufferRemoteAddrStr,$ThisIp)!=0 ){
echo "消费机的远程服务器IP不是指向当前网卡,请在消费机上 功能1>\7IP地址及端口设定 设定正确的网络参数!\n\n";
}
}
break;
case "101": ///*接收到设备的开的信号*/
$DevRecFramesStr = $Fields[1]; /*包序列号 */
$DevBufferIpAddrStr = $Fields[2]; /*终端IP */
$DevBufferRemoteAddrStr = $Fields[3]; /*远程电脑指机IP*/
$DevBufferMachinStr = $Fields[4]; /*机号*/
$DevBufferDatetimeStr = $Fields[5]; /*设备日期时间*/
if(sizeof($Fields)>6){ /*2018年以后的设备有唯一硬件序号*/
$DevBufferSerialNumStr=$Fields[6];
}
$SendInfStr="001,".$DevRecFramesStr; //确定接收到信息,否则设备会连续发送三次
SendInfToIp($socket,$SendInfStr,$peer);
$GetDT=substr($DevBufferDatetimeStr,0,16);
$SysDT=substr(date('Y-m-d H:i:s',time()),0,16);
if (strcmp($GetDT,$SysDT)!=0){ /*设备时钟与系统不符,更新设备时间*/
$SendInfStr="003," . $DevBufferMachinStr ."," . date('Y-m-d H:i:s', time());
SendInfToIp($socket,$SendInfStr,$peer);
}
break;
case "150":
$DevRecFramesStr = $Fields[1]; /*包序列号 */
$DevBufferIpAddrStr = $Fields[2]; /*终端IP */
$DevBufferRemoteAddrStr = $Fields[3]; /*远程电脑指机IP*/
$DevBufferMachinStr = $Fields[4]; /*机号*/
$DevBufferCardidStr = $Fields[5]; /*卡号*/
$DevBufferReaderStr= $Fields[6]; /*读头号*/
$DevBufferDoorNoStr= $Fields[7]; /*门或继电器号*/
$DevBufferDelayStr= $Fields[8]; /*门磁未关秒数,0表示已关*/
$DevBufferPasswPropStr= $Fields[9]; /*密码属性(0密码无效,1刷卡后按密码,2补签密码,3开门密码,4防迫胁密码)*/
$DevBufferPassWStr= $Fields[10]; /*密码(最多8位数字)*/
$DevBufferUseTimeStr= $Fields[11]; /*刷卡时间*/
if(sizeof($Fields)>12){ /*2018年以后的设备有唯一硬件序号*/
$DevBufferSerialNumStr=$Fields[12];
}
$SendInfStr="001,".$DevRecFramesStr; //确定接收到信息,否则设备会连续发送三次
SendInfToIp($socket,$SendInfStr,$peer);
$LastFramesStr=$peer.$inMsg; //将接收到的信息接保存,用于对比是否重复接收到的信息
//可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息
//用050指令返回开门成功,
//用051指令返回开门失败,正式系统开发时要有重发机制 */
//$SendInfStr="051," . $DevBufferMachinStr . "," . $DevBufferCardidStr . ",卡号:" . $DevBufferCardidStr . "\\n姓名:张三丰 \\n状态:无效卡\\n,20,1,3";
$SendInfStr="050," . $DevBufferMachinStr . "," . $DevBufferCardidStr . ",卡号:" . $DevBufferCardidStr . "\\n姓名:张三丰 \\n状态:欢迎关临\\n,20,1,0," . $DevBufferReaderStr . "," . $DevBufferDoorNoStr . ",5,20" ;
SendInfToIp($socket,$SendInfStr,$peer);
default:
//更多的字段信息及反馈指令,请仔细查看设备的通讯协议说明......
}
} while ($inMsg !== false);
//判断字符串是否一个合法的日期时间--------------------------------------------------------------------------------------------------------
function CheckDateTime($data)
{
if(date('Y-m-d H:i:s',strtotime($data))==$data){
return true;
}else{
return false;
}
}
//确定接收到设备上传的数,以免设备重复发送--------------------------------------------------------------------------------------------------
function SendInfToIp($socket,$SendInfStr,$peer)
{
stream_socket_sendto($socket,$SendInfStr,0,$peer);
//$handle = stream_socket_client("udp://".$peer, $errno, $errstr);
//fwrite($handle, $SendInfStr);
echo "SendTo IP:".$peer."\n";
echo "SendInfor:{$SendInfStr}\n\n";
}
//获取本机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';
}
}
?>