本示例使用的设备: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();
}
}