Java UDP Socket 实时在线刷卡扫码POS消费机门禁控制板服务端示例源码

发布于:2025-06-23 ⋅ 阅读:(17) ⋅ 点赞:(0)

本示例使用的设备:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.52de2c1bYG0BuO&ft=t&id=17021194999

一、获取本电脑所有网卡IP 

public static String getIP() {
	Enumeration<NetworkInterface> netInterfaces;
	ArrayList<String> IpAddList = new ArrayList<String>();
	try {
		netInterfaces = NetworkInterface.getNetworkInterfaces();    // 拿到所有网卡
		InetAddress ip;
		while (netInterfaces.hasMoreElements()) {
			NetworkInterface ni = netInterfaces.nextElement();
			Enumeration<InetAddress> addresses = ni.getInetAddresses();
			while (addresses.hasMoreElements()) {
				ip = addresses.nextElement();
				if (!ip.isLoopbackAddress() && ip.getHostAddress().indexOf(':') == -1) {
					IpAddList.add(ip.getHostAddress());
					System.out.println((IpAddList.size() - 1) + "" + " " + ni.getName() + " " + ip.getHostAddress());
				}
			}
		}
	} catch (Exception e) {
	}
	if (IpAddList.isEmpty()) {
		return "127.0.0.1";
	} else {
		return IpAddList.get(0);    //如有多张网卡,请选择与设备相连的网卡,否则无法与设备正常通讯
	}
}

二、服务端开启UDP端口接收消费机提交的请求

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;

public class Main {
    public static void main(String[] args) throws Exception{
        String MyIpAdd=getIP();        //获取电脑网卡IP
        int MyPort=39192;              //监听端口  
        InetAddress Addip=InetAddress.getByName(MyIpAdd) ;
        DatagramSocket s = new DatagramSocket(MyPort);            /** 1、建立udp socket端点 */
        System.out.println("当前系统绑定的网卡:"+MyIpAdd+":"+String.format("%d",MyPort));
        while(true){
            byte [] bbuf = new byte [1024];                       /**2、预先创建接收数据存放的位置,封装*/
            DatagramPacket rdp = new DatagramPacket(bbuf,bbuf.length);
            s.receive(rdp);                                       /**3、使用receive阻塞式接收*/
            String ReceiveDataStr=new String(rdp.getData());
            String RemoteHostIP=rdp.getAddress().getHostAddress();
            int RemotePort=rdp.getPort();
            System.out.println("From ip::"+rdp.getAddress().getHostAddress()+"\nport::"+rdp.getPort()+"\ndata::"+ReceiveDataStr+"\n\n");

            String[] strArr = ReceiveDataStr.split("\\,");    /*分割接收到的数据后再分析、处理、返回指令 */
        }
    }
}

三、接收到消费机上传的刷卡数据

if (strArr[0].equals("102")){				/*接收到直接刷卡的信息*/
	DevRecFramesStr = strArr[1];            /*包序列号 */
	DevBufferIpAddrStr = strArr[2];         /*终端IP  */
	DevBufferRemoteAddrStr = strArr[3];     /*远程电脑指机IP*/
	DevBufferMachinStr = strArr[4];         /*机号*/
	DevBufferCardidStr = strArr[5];         /*卡号*/
	if(strArr.length>6){                    /*2018年以后的设备有唯一硬件序号*/
		DevBufferSerialNumStr=strArr[6];
	}

	SendInfStr="001,"+DevRecFramesStr;       /*向设备发此数据表示已收到信息,否则设备会连续发三次*/
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);

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

	/*009指令返回持卡人信息*/
	SendInfStr="009," + DevBufferMachinStr + ",卡号:" + DevBufferCardidStr + "\\n姓名:张三丰\\n余额:888.88\\n状态:卡可正常使用\\n,20,1,0" ;
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);
}

四、接收到消费机上传的现金支付请求

if (strArr[0].equals("103")){				/*接收到 输入消费金额后刷卡、消费机定额消费、消费机计次消费 的上传信息 */
	DevRecFramesStr = strArr[1];            /*包序列号 */
	DevBufferIpAddrStr = strArr[2];         /*终端IP  */
	DevBufferRemoteAddrStr = strArr[3];     /*远程电脑指机IP*/
	DevBufferMachinStr = strArr[4];         /*机号*/
	DevBufferCardidStr = strArr[5];         /*卡号*/
	DevBufferUseMoneryStr= strArr[6];       /*消费金额*/
	DevBufferUseTimeStr= strArr[7];         /*消费时间*/
	if(strArr.length>8){                    /*2018年以后的设备有唯一硬件序号*/
		DevBufferSerialNumStr=strArr[8];
	}

	SendInfStr="001,"+DevRecFramesStr;       /*向设备发此数据表示已收到信息,否则设备会连续发三次*/
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);

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

	/*008指令返回本次消费成功,006指令返回本次消费失败,正式系统开发时要有重发机制*/
	SendInfStr="008," + DevBufferMachinStr + "," + DevBufferCardidStr+ ","+DevBufferUseMoneryStr+"," + "姓名:张三丰 {123.45}\\n,20,0,1" ;
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);
}

五、接收到消费机上传的计次消费请求

if (strArr[0].equals("104")){				/*接收到 计次消费模式下,终端刷卡后设备向电脑发送此信息 */
	DevRecFramesStr = strArr[1];            /*包序列号 */
	DevBufferIpAddrStr = strArr[2];         /*终端IP  */
	DevBufferRemoteAddrStr = strArr[3];     /*远程电脑指机IP*/
	DevBufferMachinStr = strArr[4];         /*机号*/
	DevBufferCardidStr = strArr[5];         /*卡号*/
	DevBufferUseTimeStr= strArr[6];         /*消费时间*/
	if(strArr.length>7){                    /*2018年以后的设备有唯一硬件序号*/
		DevBufferSerialNumStr=strArr[7];
	}

	SendInfStr="001,"+DevRecFramesStr;       /*向设备发此数据表示已收到信息,否则设备会连续发三次*/
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);

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

	/*008指令返回本次消费成功,006指令返回本次消费失败,正式系统开发时要有重发机制*/
	SendInfStr="006," + DevBufferMachinStr + "," + DevBufferCardidStr+ "," + "姓名:张三丰 \\n余额:123.45\\n状态:累计次数超出\\n,20,0,14" ;
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);
}

六、接收到消费机上传的记账消费记录

if (strArr[0].equals("105")){				/*接收到 脱网记账消费记录,消费机开启记账功能,有脱机记账消费记录网络恢复正常自动向电脑发送此信息 */
	DevRecFramesStr = strArr[1];            /*包序列号 */
	DevBufferIpAddrStr = strArr[2];         /*终端IP  */
	DevBufferRemoteAddrStr = strArr[3];     /*远程电脑指机IP*/
	DevBufferMachinStr = strArr[4];         /*机号*/
	DevBufferCardidStr = strArr[5];         /*卡号*/
	DevBufferUseMoneryStr= strArr[6];       /*消费金额*/
	DevBufferUseTimeStr= strArr[7];         /*消费时间*/
	DevBufferStaryStr= strArr[8];           /*消费方式  0扣费 1计次*/
	DevBufferRecordAddStr= strArr[9];       /*记录地址标识*/
	DevBufferAllNoStr= strArr[10];          /*总计录数*/
	if(strArr.length>11){                   /*2018年以后的设备有唯一硬件序号*/
		DevBufferSerialNumStr=strArr[11];
	}

	SendInfStr="001,"+DevRecFramesStr;       /*向设备发此数据表示已收到信息,否则设备会连续发三次*/
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);

	if(!IsDateTime(DevBufferUseTimeStr)){      /*判断消费时间是否正确*/
		DevBufferUseTimeStr= "9999-99-99 99:99:99";   /*如果消费时间不正确,需更为 9999-99-99 99:99:99 才能将此条记录删除 */
	}

	/*清除设备内当前这条已上传的记录,驱动设备继续上传剩下的记录*/
	SendInfStr="011," + DevBufferMachinStr + "," + DevBufferCardidStr + "," + DevBufferUseMoneryStr + "," + DevBufferUseTimeStr + "," + DevBufferRecordAddStr;
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);   执行此指令将清除消费机内当前已上传的记录,清除后消费机继续将后一条记录上传,直到全部记㥆上传完毕
}

七、接收到消费机上传的按键信息

if (strArr[0].equals("106")){				/*接收到设备的按键信息*/
	DevRecFramesStr = strArr[1];            /*包序列号 */
	DevBufferIpAddrStr = strArr[2];         /*终端IP  */
	DevBufferRemoteAddrStr = strArr[3];     /*远程电脑指机IP*/
	DevBufferMachinStr = strArr[4];         /*机号*/
	DevBufferInputKeyStr= strArr[5];        /*按键信息*/
	if(strArr.length>6){                    /*2018年以后的设备有唯一硬件序号*/
		DevBufferSerialNumStr=strArr[6];
	}

	SendInfStr="001,"+DevRecFramesStr;      /*向设备发此数据表示已收到信息,否则设备会连续发三次*/
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);
}

八、接收到消费机上传的扫码支付请求 

if (strArr[0].equals("128")){				/*接收到消费金额及扫码信息*/
	DevRecFramesStr = strArr[1];            /*包序列号 */
	DevBufferIpAddrStr = strArr[2];         /*终端IP  */
	DevBufferRemoteAddrStr = strArr[3];     /*远程电脑指机IP*/
	DevBufferMachinStr = strArr[4];         /*机号*/
	DevBufferCommandStr = strArr[5];        /*口令*/
	DevBufferUseMoneryStr= strArr[6];       /*消费金额*/
	DevBufferUseTimeStr= strArr[7];         /*消费时间*/
	DevBufferQrcodeInfStr="";
	if(strArr.length>9){                    //防止二维码信息中有分隔符,
		for(j=9;j<strArr.length-1;j++){
			DevBufferQrcodeInfStr=DevBufferQrcodeInfStr+strArr[j];
		}
		DevBufferQrcodeInfStr=DevBufferQrcodeInfStr.trim();
		DevBufferSerialNumStr=strArr[strArr.length-1];       /*2018年以后的设备有唯一硬件序号*/
	}

	SendInfStr="001,"+DevRecFramesStr;      /*向设备发此数据表示已收到信息,否则设备会连续发三次*/
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);

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

	/*008指令返回本次消费成功,006指令返回本次消费失败,正式系统开发时要有重发机制*/
	SendInfStr="008," + DevBufferMachinStr + "," + DevBufferCommandStr+ ","+DevBufferUseMoneryStr+"," + "正在进行扫码支付..{请不要按动键盘!    \n},5,0,1" ;
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);
}

九、接收到消费机开机信号

if (strArr[0].equals("101")){				/*有设备开机的信号*/
	DevRecFramesStr = strArr[1];            /*包序列号 */
	DevBufferIpAddrStr = strArr[2];         /*终端IP  */
	DevBufferRemoteAddrStr = strArr[3];     /*远程电脑指机IP*/
	DevBufferMachinStr = strArr[4];         /*机号*/
	DevBufferDatetimeStr = strArr[5];       /*日期时间*/
	if(strArr.length>6){                    /*2018年以后的设备有唯一硬件序号*/
		DevBufferSerialNumStr=strArr[6];
	}

	String SysNowTime=GetSysDT();           /*取系统时间*/
	if(DevBufferDatetimeStr.substring(0,16).compareTo(SysNowTime.substring(0,16))!=0){
		SendInfStr="003,"+DevBufferMachinStr+","+SysNowTime;       /*设备时钟与系统不符,更新设备时间*/
		SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);
	}
}

门禁控制板介绍: https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.52de2c1bIqEgQP&ft=t&id=599136536796

十、接收到门禁控制板的刷卡开门请求

case "150":                                 /*接收到实时考勤门禁机刷卡数据*/
	DevRecFramesStr = strArr[1];            /*包序列号 */
	DevBufferIpAddrStr = strArr[2];         /*终端IP  */
	DevBufferRemoteAddrStr = strArr[3];     /*远程电脑指机IP*/
	DevBufferMachinStr = strArr[4];         /*机号*/
	DevBufferCardidStr= strArr[5];          /*卡号*/
	DevBufferReaderStr= strArr[6];          /*读头号*/
	DevBufferDoorNoStr= strArr[7];          /*门或继电器号*/
	DevBufferDelayStr= strArr[8];           /*门磁未关秒数,0表示已关*/
	DevBufferPasswPropStr= strArr[9];       /*密码属性(0密码无效,1刷卡后按密码,2补签密码,3开门密码,4防迫胁密码)*/
	DevBufferPassWStr= strArr[10];          /*密码(最多8位数字)*/
	DevBufferUseTimeStr= strArr[11];        /*刷卡时间*/
	if(strArr.length>12){                    /*2018年以后的设备有唯一硬件序号*/
		DevBufferSerialNumStr=strArr[12];
	}

	SendInfStr="001,"+DevRecFramesStr;      /*向设备发此数据表示已收到信息,否则设备会连续发三次*/
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);

	/*用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" ;
	SendInfToDiv(s,SendInfStr,RemoteHostIP,RemotePort);

十一、服务端回应消费机的指令 

static void SendInfToDiv(DatagramSocket s,String Sendinf,String RemoIp,int RemoPro) throws Exception{
	byte[] SendBuf = Sendinf.getBytes("gb2312");         /** 发送数据,封装打包 */
	DatagramPacket dp1 = new DatagramPacket(SendBuf, SendBuf.length, InetAddress.getByName(RemoIp), RemoPro);
	try {
		s.send(dp1);
		System.out.println("SendTo ip::"+RemoIp+"\nport::"+String.valueOf(RemoPro)+"\ndata::"+Sendinf+"\n\n");
	} catch (IOException e) {
		System.out.println("发送失败: ");
		e.printStackTrace();
	}
}


网站公告

今日签到

点亮在社区的每一天
去签到