RFID网络读写器介绍:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-17663462238.11.12cd5b43ejf7s9&id=17029933847
package UdpDemo;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.net.*;
import java.util.*;
//udp传输: 接收
/**步骤:---
* 1、建立udp socket,设置接收端口
* 2、预先创建数据存放的位置,封装
* 3、使用receive阻塞式接收
* 4、关闭资源
* */
public class ReaderDemo {
public static void main(String[] args) throws Exception{
String MyIpAdd=getIP();
InetAddress Addip=InetAddress.getByName(MyIpAdd) ;
DatagramSocket s = new DatagramSocket(39169,Addip); /** 1、建立udp socket端点 */
System.out.println("当前软件绑定的IP:"+MyIpAdd+":39169\n\n");
String SendInfStr="a6";
byte[] SendBuf = new byte[1]; /** 2、提供发送数据,封装打包 a6 为搜索在线设备的指令 */
SendBuf[0]=(byte)0xa6;
DatagramPacket dp = new DatagramPacket(SendBuf, SendBuf.length, InetAddress.getByName("255.255.255.255"), 39169);
try {
s.send(dp);
System.out.println("SendTo ip::255.255.255.255\nport::39169\ndata::"+SendInfStr);
System.out.println("电脑发送搜索在线设备的指令"+"\n\n");
} catch (IOException e) {
System.out.println("发送失败: ");
e.printStackTrace();
}
byte [] readcardbuf= new byte[1000]; /** ic卡扇区内数据*/
byte [] LastBuf =new byte[9]; /** 用于保存最后上传的信息*/
boolean i=true;
while(i){
int p=0;
int j=0;
int m=0;
byte [] bbuf = new byte [1024]; /**3、预先创建接收数据存放的位置,封装*/
DatagramPacket rdp = new DatagramPacket(bbuf,bbuf.length);
s.receive(rdp); /**4、使用receive阻塞式接收*/
String RemoteHostIP=rdp.getAddress().getHostAddress(); /*数据来源IP */
int RemotePort=rdp.getPort(); /*数据来源端口*/
int length = rdp.getLength();
byte[] data= rdp.getData();
String ReceiveDataStr="";
String bytestr="";
String CardNo16="";
String SerialNum="";
String CardNoStr="";
String CardInfStr="";
long cardno10;
long cardnum;
for(p=0;p<length;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
ReceiveDataStr=ReceiveDataStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
System.out.println("From ip::"+rdp.getAddress().getHostAddress()+"\nport::"+rdp.getPort()+"\ndata::"+ReceiveDataStr);
if(length>=8){ //判断是否是重复上传的数据包
if(data[0]==LastBuf[0] && data[1]==LastBuf[1] && data[2]==LastBuf[2] && data[3]==LastBuf[3] && data[4]==LastBuf[4] && data[5]==LastBuf[5] && data[6]==LastBuf[6] && data[7]==LastBuf[7] && data[8]==LastBuf[8]){
DisableSendAge(s,data,length,RemoteHostIP,RemotePort); //向读卡器发确认信息,否则读卡器会连续发三次
System.out.println("\n\n"); // 重复的上传的数据不分析处理,直接丢弃
}else{
for(p=0;p<9;p++){
LastBuf[p]=data[p]; /*将当前接收到的数据保存,用于再次接收到数据时比对*/
}
switch(data[0]){
case (byte)0xf2:
System.out.println("在线读卡器响应搜索指令");
System.out.println("指令码 :"+Integer.toHexString(data[0] & 0xff));
System.out.println("设备IP :"+Integer.toString(data[1] & 0xff)+"."+Integer.toString(data[2] & 0xff)+"."+Integer.toString(data[3] & 0xff)+"."+Integer.toString(data[4] & 0xff));
System.out.println("掩 码 :"+Integer.toString(data[5] & 0xff)+"."+Integer.toString(data[6] & 0xff)+"."+Integer.toString(data[7] & 0xff)+"."+Integer.toString(data[8] & 0xff));
System.out.println("端口号 :"+Integer.toString((data[9] & 0xff)+((data[10] & 0xff) *256)));
System.out.println("机 号 :"+Integer.toString((data[11] & 0xff)+((data[12] & 0xff) *256)));
System.out.println("网 关 :"+Integer.toString(data[13] & 0xff)+"."+Integer.toString(data[14] & 0xff)+"."+Integer.toString(data[15] & 0xff)+"."+Integer.toString(data[16] & 0xff));
for(p=17;p<23;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
if(p<22){SerialNum=SerialNum+"-";}
}
System.out.println("网关MAC :"+SerialNum);
String ServerIp=Integer.toString(data[23] & 0xff)+"."+Integer.toString(data[24] & 0xff)+"."+Integer.toString(data[25] & 0xff)+"."+Integer.toString(data[26] & 0xff);
System.out.println("远程服务器IP:"+ServerIp);
//System.out.println("远程服务器IP:"+Integer.toString(data[23] & 0xff)+"."+Integer.toString(data[24] & 0xff)+"."+Integer.toString(data[25] & 0xff)+"."+Integer.toString(data[26] & 0xff));
SerialNum="";
for(p=27;p<33;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
if(p<32){SerialNum=SerialNum+"-";}
}
System.out.println("服务器MAC :"+SerialNum);
System.out.println("网络标识 :"+Integer.toHexString(data[33] & 0xff));
System.out.println("响声标识 :"+Integer.toHexString(data[34] & 0xff));
SerialNum="";
String DeviceMAC="16-88-";
for(p=35;p<39;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
DeviceMAC=DeviceMAC+ bytestr.substring(bytestr.length() -2,bytestr.length());
SerialNum=SerialNum +Integer.toString(data[p] & 0xff);
if(p<38){
SerialNum=SerialNum+"-";
DeviceMAC=DeviceMAC+"-";
}
}
System.out.println("通讯模块序号:"+SerialNum);
System.out.println("设备MAC地址 :"+DeviceMAC);
if(length>39){
SerialNum="";
for(p=39;p<length;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("设备唯一序号:"+SerialNum);
}
if(ServerIp.compareTo("255.255.255.255")!=0 && ServerIp.compareTo(MyIpAdd)!=0 ){
System.out.println("读卡器的远程服务器IP未指向本设备,需将读卡器的远程服务器IP设为:"+MyIpAdd+"\n\n");
//SetNetworkPara(s,data,length,RemoteHostIP,RemotePort); //如果需要修改读卡器的IP 掩码 网关 远程服务器IP 通讯端口,取消注释,按网络环境设定正确的值
}
System.out.println("\n\n");
break;
case (byte)0xf3:
System.out.println("接收到的信息为心跳数据包");
System.out.println("指令码:"+Integer.toHexString(data[0] & 0xff));
System.out.println("设备IP:"+Integer.toString(data[1] & 0xff)+"."+Integer.toString(data[2] & 0xff)+"."+Integer.toString(data[3] & 0xff)+"."+Integer.toString(data[4] & 0xff));
System.out.println("机器号:"+Integer.toString((data[5] & 0xff)+((data[6] & 0xff) *256)));
System.out.println("包序号:"+Integer.toString((data[7] & 0xff)+((data[8] & 0xff) *256)));
System.out.println("心跳码:"+Integer.toHexString(data[9] & 0xff));
System.out.println("长 度:"+Integer.toHexString(data[10] & 0xff));
System.out.println("继电器:"+Integer.toHexString(data[11] & 0xff));
System.out.println("按键值:"+Integer.toHexString(data[12] & 0xff));
for(p=13;p<17;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("随机码:"+SerialNum);
SerialNum="";
for(p=17;p<length;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("设备序列号:"+SerialNum+"\n\n");
break;
case (byte)0xf8:
break;
case (byte)0xc1: /*接收到的信息为IC只读上传的IC卡号*/
System.out.println("接收到的信息为IC只读上传的IC卡号");
System.out.println("指令码:"+Integer.toHexString(data[0] & 0xff));
System.out.println("设备IP:"+Integer.toString(data[1] & 0xff)+"."+Integer.toString(data[2] & 0xff)+"."+Integer.toString(data[3] & 0xff)+"."+Integer.toString(data[4] & 0xff));
System.out.println("机器号:"+Integer.toString((data[5] & 0xff)+((data[6] & 0xff) *256)));
System.out.println("包序号:"+Integer.toString((data[7] & 0xff)+((data[8] & 0xff) *256)));
for(p=10;p<14;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
CardNo16=CardNo16+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("16进制卡号:"+CardNo16);
cardnum=data[10] & 0xff;
cardnum=cardnum+(data[11] & 0xff) *256;
cardnum=cardnum+(data[12] & 0xff) *65536;
cardnum=cardnum+(data[13] & 0xff) *16777216;
cardno10 = 0;
for (j=28; j>=0; j-=4) {
cardno10 = cardno10<<4 | (cardnum>>>j & 0xF);
}
CardNoStr = String.format("%010d", cardno10);
System.out.println("10进制卡号:"+CardNoStr);
for(p=14;p<length;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("设备序列号:"+SerialNum+"\n\n");
DisableSendAge(s,data,length,RemoteHostIP,RemotePort); //向读卡器发确认信息,否则读卡器会连续发三次
if(args.length==0)
{
SendDispBeep(s,CardNoStr,RemoteHostIP,RemotePort); //无参数时,发送显示及固定组合声音
}
else
{
SendDispSpk(s,CardNoStr,RemoteHostIP,RemotePort); //有参数时,发送显示及TTS声音
}
//Thread.sleep(10);
//ReadCardInf(s,data,length,RemoteHostIP,RemotePort); //如果是网络读写器,可以继续发指令读写
break;
case (byte)0xc3: /*全扇区读写器收到读卡扇区内的数据*/
j=data[10] *48;
m=data[11] *48;
for(p=0;p<m;p++){
readcardbuf[j+p]=data[16+p];
}
if(data[11]+data[10]>=data[9]){ /*已完全收到所有包数据,一个数据包最多传4个扇区的数据,如果读写器设备读写扇区数大于4,数据要分2个包上传,扇区数大于8要分3个包,大与12要分4个包上传*/
System.out.println("接收到的信息为IC卡扇区内数据");
System.out.println("指令码:"+Integer.toHexString(data[0] & 0xff));
System.out.println("设备IP:"+Integer.toString(data[1] & 0xff)+"."+Integer.toString(data[2] & 0xff)+"."+Integer.toString(data[3] & 0xff)+"."+Integer.toString(data[4] & 0xff));
System.out.println("机器号:"+Integer.toString((data[5] & 0xff)+((data[6] & 0xff) *256)));
System.out.println("包序号:"+Integer.toString((data[7] & 0xff)+((data[8] & 0xff) *256)));
for(p=12;p<16;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
CardNo16=CardNo16+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("16进制卡号:"+CardNo16);
SerialNum="";
for(int o=16+m;o<length;o++){
bytestr="00"+Integer.toHexString(data[o] & 0xff);
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("设备序列号:"+SerialNum+",读卡数据已全部接收完成!");
m=data[9] *48;
CardInfStr="";
for(p=0;p<m;p++){
bytestr="00"+Integer.toHexString(readcardbuf[p] & 0xff);
CardInfStr=CardInfStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
System.out.println("卡片内数据:"+CardInfStr);
}
else{
SerialNum="";
for(int o=16+p;o<length;o++){
bytestr="00"+Integer.toHexString(data[o] & 0xff);
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("设备序列号:"+SerialNum+",读卡数据还未全部接收完,需将全部数据接收完整再处理!");
}
System.out.println("\n\n");
break;
case (byte)0xc5: /*指定区号、密码读卡返回信息*/
System.out.println("接收到的信息为IC卡扇区内数据");
System.out.println("指令码:"+Integer.toHexString(data[0] & 0xff));
System.out.println("设备IP:"+Integer.toString(data[1] & 0xff)+"."+Integer.toString(data[2] & 0xff)+"."+Integer.toString(data[3] & 0xff)+"."+Integer.toString(data[4] & 0xff));
System.out.println("机器号:"+Integer.toString((data[5] & 0xff)+((data[6] & 0xff) *256)));
for(p=8;p<12;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
CardNo16=CardNo16+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("16进制卡号:"+CardNo16);
System.out.println("扇区数:"+Integer.toHexString(data[7] & 0xff));
System.out.println("扇区号:"+Integer.toHexString(data[12] & 0xff));
if(data[13]==0){
CardInfStr="";
for(p=0;p<48;p++){
bytestr="00"+Integer.toHexString(data[14+p] & 0xff);
CardInfStr=CardInfStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
System.out.println("扇区内数据:"+CardInfStr);
System.out.println("\n\n");
WriteCard(s,data,length,RemoteHostIP,RemotePort); //写卡操作
} else{
if(data[13]==12){
System.out.println("卡密码认证失败!");
System.out.println("\n\n");
}else {
System.out.println("读卡失败,错误代码:"+Integer.toString(data[13]));
System.out.println("\n\n");
}
}
break;
case (byte)0xcD : /*响应写卡、更改卡密码*/
System.out.println("设备IP:"+Integer.toString(data[2] & 0xff)+"."+Integer.toString(data[3] & 0xff)+"."+Integer.toString(data[4] & 0xff)+"."+Integer.toString(data[5] & 0xff));
System.out.println("机器号:"+Integer.toString((data[6] & 0xff)+((data[7] & 0xff) *256)));
for(p=9;p<13;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
CardNo16=CardNo16+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("16进制卡号:"+CardNo16);
System.out.println("扇区号:"+Integer.toHexString(data[13] & 0xff));
if(data[1]==0x3A){
if(data[14]==0x00){
System.out.println("更改卡密码成功!");
}else{
System.out.println("更改卡密码失败,错误代码:"+Integer.toString(data[14]));
}
}else{
if(data[1]==0x3D){
if(data[14]==0x00){
System.out.println("写卡成功!");
}else{
System.out.println("写卡失败,错误代码:"+Integer.toString(data[14]));
}
}
}
System.out.println("\n\n");
break;
case (byte)0xcf : /*接收到IC卡离开读卡器的信息*/
case (byte)0xdf : /*接收到ID卡离开读卡器的信息*/
System.out.println("接收到卡离开读卡器的信息");
System.out.println("指令码:"+Integer.toHexString(data[0] & 0xff));
System.out.println("设备IP:"+Integer.toString(data[1] & 0xff)+"."+Integer.toString(data[2] & 0xff)+"."+Integer.toString(data[3] & 0xff)+"."+Integer.toString(data[4] & 0xff));
System.out.println("机器号:"+Integer.toString((data[5] & 0xff)+((data[6] & 0xff) *256)));
System.out.println("包序号:"+Integer.toString((data[7] & 0xff)+((data[8] & 0xff) *256)));
if(data[0]==(byte)0xcf){
for(p=11;p<15;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
CardNo16=CardNo16+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
}else{
for(p=10;p<15;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
CardNo16=CardNo16+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
}
System.out.println("16进制卡号:"+CardNo16+"\n\n");
DisableSendAge(s,data,length,RemoteHostIP,RemotePort); //向读卡器发确认信息,否则读卡器会连续发三次
break;
case (byte)0xd1: /*接收到的信息为ID读卡器上传的卡号*/
System.out.println("接收到的信息为ID读卡器上传的卡号");
System.out.println("指令码:"+Integer.toHexString(data[0] & 0xff));
System.out.println("设备IP:"+Integer.toString(data[1] & 0xff)+"."+Integer.toString(data[2] & 0xff)+"."+Integer.toString(data[3] & 0xff)+"."+Integer.toString(data[4] & 0xff));
System.out.println("机器号:"+Integer.toString((data[5] & 0xff)+((data[6] & 0xff) *256)));
System.out.println("包序号:"+Integer.toString((data[7] & 0xff)+((data[8] & 0xff) *256)));
for(p=9;p<13;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
CardNo16=CardNo16+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("16进制卡号:"+CardNo16);
cardnum=data[9] & 0xff;
cardnum=cardnum+(data[10] & 0xff) *256;
cardnum=cardnum+(data[11] & 0xff) *65536;
cardnum=cardnum+(data[12] & 0xff) *16777216;
cardno10 = 0;
for (j=28; j>=0; j-=4) {
cardno10 = cardno10<<4 | (cardnum>>>j & 0xF);
}
CardNoStr = String.format("%010d", cardno10);
System.out.println("10进制卡号:"+CardNoStr);
for(p=14;p<length;p++){
bytestr="00"+Integer.toHexString(data[p] & 0xff);
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("设备序列号:"+SerialNum);
System.out.println("\n\n");
DisableSendAge(s,data,length,RemoteHostIP,RemotePort); //向读卡器发确认信息,否则读卡器会连续发三次
if(args.length==0)
{
SendDispBeep(s,CardNoStr,RemoteHostIP,RemotePort); //无参数时,发送显示及固定组合声音
}
else
{
SendDispTTS(s,CardNoStr,RemoteHostIP,RemotePort); //有参数时,发送显示及TTS声音
}
break;
default:
}
}
}else{
System.out.println("\n\n");
}
}
s.close(); /**5、关闭资源*/
}
/*------------------------------------------------------------------------------------------------------------向读卡器发送显示文字+继电器+TTS合成语音*/
static void SendDispTTS(DatagramSocket s,String CardNum,String RemoteHostIP,int RemotePort) throws Exception{
//DatagramSocket s1 = new DatagramSocket(); /** 1、建立udp socket端点 */
String DispStr="卡号:"+CardNum+" "+GetSysDT().substring(2,19)+" "; //将显示的文字生成字节数组
byte[] DispBuf= DispStr.getBytes("gb2312");
String SpeakStr=""; //将要播报的TTS语音生成字节数组,最大不能超过126个字节
SpeakStr="[v10]"; //定义语音大小,最大语语音为16,可加在任何地方
SpeakStr=SpeakStr+"欢迎您使用我们的网络读卡器"; //要播报的中文语音
byte[] SpeakBuf= SpeakStr.getBytes("gb2312");
int SpeakLen=SpeakBuf.length; //语音长度
int SendLen=11+34+SpeakLen+4; //总计发送数据长度
byte[] SendBuf1 = new byte [180]; /** 2、将要发送的数据打包 */
SendBuf1[0]=(byte)0x5C; //指令码
SendBuf1[1]=(byte)0x00; //机号低
SendBuf1[2]=(byte)0x00; //机号高,如果高低位都为0表示任意机号
SendBuf1[3]=(byte)0x01; //蜂鸣声代码
SendBuf1[4]=(byte)0xF0; //继电器代码 F0表示全部继电器 F1表示1号继电器 F2表示2号继电器
SendBuf1[5]=(byte)0x20; //继电器开启时长 低位
SendBuf1[6]=(byte)0x00; //继电器开启时长 高位
SendBuf1[7]=(byte)0x14; //显示保留时间,单位为秒,为0xFF时表示永久显示
SendBuf1[8]=(byte)0x00; //在显示屏中的哪个位置开始
SendBuf1[9]=(byte)0x22; //显示字符串长度 为全屏显示为 34 个字符
SendBuf1[10]=(byte)SpeakLen; //语音长度
for(int i=0;i<34;i++){ //显示的文字信息
SendBuf1[i+11]=DispBuf[i];
}
for(int i=0;i<SpeakLen;i++){ //TTS语音播报信息
SendBuf1[i+45]=SpeakBuf[i];
}
SendBuf1[10+34+SpeakLen+1]=(byte)0x55; //固定的抗干扰后缀
SendBuf1[10+34+SpeakLen+2]=(byte)0xaa;
SendBuf1[10+34+SpeakLen+3]=(byte)0x66;
SendBuf1[10+34+SpeakLen+4]=(byte)0x99;
DatagramPacket dp1 = new DatagramPacket(SendBuf1, SendLen, InetAddress.getByName(RemoteHostIP), RemotePort);
try { /** 3、 发送数据 **/
s.send(dp1);
String SendInfStr=""; //这段代码显示发送的16进制报文,正式项目可以删除
for(int p=0;p<SendLen;p++){
String bytestr="00"+Integer.toHexString(SendBuf1[p] & 0xff);
SendInfStr=SendInfStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
System.out.println("SendTo ip::"+RemoteHostIP+"\nport::"+RemotePort+"\ndata::"+SendInfStr);
System.out.println("发送文字显示及TTS语音\n\n");
} catch (IOException e) {
System.out.println("发送失败: ");
e.printStackTrace();
}
//s1.close(); /**4、关闭资源*/
}
/*-----------------------------------------------------------------------------------------------------------向读卡器发送显示+继电器+固定组合语音*/
static void SendDispSpk(DatagramSocket s,String CardNum,String RemoteHostIP,int RemotePort) throws Exception{
//DatagramSocket s1 = new DatagramSocket(); /** 1、建立udp socket端点 */
String DispStr="卡号:"+CardNum+" "+GetSysDT().substring(2,19)+" "; //将显示的文字生成字节数组
byte[] DispBuf= DispStr.getBytes("gb2312");
byte SpkLen=3; //固定组合语音长度,一次最大取值21条
byte[] SpkBuf=new byte[SpkLen]; //固定组合语音代码缓冲,
SpkBuf[0]=55; //要播报的语音代码0
SpkBuf[1]=41; //要播报的语音代码1
SpkBuf[2]=53; //要播报的语音代码2......
byte[] SendBuf1 = new byte [70]; /** 2、将要发送的数据打包 */
SendBuf1[0]=(byte)0x5B; //指令码
SendBuf1[1]=(byte)0x00; //机号低
SendBuf1[2]=(byte)0x00; //机号高,如果高低位都为0表示任意机号
SendBuf1[3]=(byte)0x02; //蜂鸣声代码,取值范围参看通讯协议
SendBuf1[4]=(byte)0xF0; //继电器代码 F0表示全部继电器 F1表示1号继电器 F2表示2号继电器
SendBuf1[5]=(byte)0x20; //继电器开启时长 低位
SendBuf1[6]=(byte)0x00; //继电器开启时长 高位
SendBuf1[7]=(byte)0x14; //显示保留时间,单位为秒,为0xFF时表示永久显示
SendBuf1[8]=(byte)0x00; //在显示屏中的哪个位置开始,一般取0表示首位
SendBuf1[9]=36; //显示字符串长度 为全屏显示为 36 个字符
SendBuf1[10]=SpkLen; //语音长度
for(int i=0;i<34;i++){ //要显示的文字
SendBuf1[11+i]=DispBuf[i];
}
for(int i=0;i<SpkLen;i++){ //要播报的固定语音代码
SendBuf1[47+i]=SpkBuf[i];
}
SendBuf1[47+SpkLen+0]=(byte)0x55; //固定的抗干扰后缀
SendBuf1[47+SpkLen+1]=(byte)0xaa;
SendBuf1[47+SpkLen+2]=(byte)0x66;
SendBuf1[47+SpkLen+3]=(byte)0x99;
DatagramPacket dp1 = new DatagramPacket(SendBuf1, SendBuf1.length, InetAddress.getByName(RemoteHostIP), RemotePort);
try { /** 3、 发送数据 **/
s.send(dp1);
String SendInfStr="";
for(int p=0;p<=47+SpkLen+3;p++){
String bytestr="00"+Integer.toHexString(SendBuf1[p] & 0xff);
SendInfStr=SendInfStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
System.out.println("SendTo ip::"+RemoteHostIP+"\nport::"+RemotePort+"\ndata::"+SendInfStr);
System.out.println("发送文字显示+鸣器响声+继电器+固定组合语音\n\n");
} catch (IOException e) {
System.out.println("发送失败: ");
e.printStackTrace();
}
//s1.close(); /**4、关闭资源*/
}
/*-----------------------------------------------------------------------------------------------------------向读卡器发送显示及蜂鸣器响声*/
static void SendDispBeep(DatagramSocket s,String CardNum,String RemoteHostIP,int RemotePort) throws Exception{
//DatagramSocket s1 = new DatagramSocket(); /** 1、建立udp socket端点 */
String DispStr="卡号:"+CardNum+" "+GetSysDT().substring(2,19)+" "; //将显示的文字生成字节数组
byte[] DispBuf= DispStr.getBytes("gb2312");
byte[] SendBuf1 = new byte [39]; /** 2、将要发送的数据打包 */
SendBuf1[0]=(byte)0x5a; //指令码
SendBuf1[1]=(byte)0x00; //机号低
SendBuf1[2]=(byte)0x00; //机号高,如果高低位都为0表示任意机号
SendBuf1[3]=(byte)0x02; //蜂鸣声代码
SendBuf1[4]=(byte)0x14; //显示时长
for(int i=0;i<34;i++){ //显示文字
SendBuf1[i+5]=DispBuf[i];
}
DatagramPacket dp1 = new DatagramPacket(SendBuf1, SendBuf1.length, InetAddress.getByName(RemoteHostIP), RemotePort);
try { /** 3、 发送数据 **/
s.send(dp1);
String SendInfStr="";
for(int p=0;p<39;p++){
String bytestr="00"+Integer.toHexString(SendBuf1[p] & 0xff);
SendInfStr=SendInfStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
System.out.println("SendTo ip::"+RemoteHostIP+"\nport::"+RemotePort+"\ndata::"+SendInfStr);
System.out.println("发送文字显示及蜂鸣器响声\n\n");
} catch (IOException e) {
System.out.println("发送失败: ");
e.printStackTrace();
}
//s1.close(); /**4、关闭资源*/
}
/*---------------------------------------------------------------------------------------------------------------接收到读卡器信息后立即回复,防止读卡器连发三次*/
static void DisableSendAge(DatagramSocket s,byte[] data,int length,String RemoteHostIP,int RemotePort) throws Exception{
if(length>=8){
//DatagramSocket s1 = new DatagramSocket(); /** 1、建立udp socket端点 */
byte[] SendBuf1 = new byte [9]; /** 2、将要发送的数据打包 */
SendBuf1[0]=(byte)0x69;
String SendInfStr="69 ";
for(int p=1;p<9;p++){
SendBuf1[p]=data[p];
String bytestr="00"+Integer.toHexString(data[p] & 0xff);
SendInfStr=SendInfStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
DatagramPacket dp1 = new DatagramPacket(SendBuf1, SendBuf1.length, InetAddress.getByName(RemoteHostIP), RemotePort);
try { /** 3、 发送数据 **/
s.send(dp1);
System.out.println("SendTo ip::"+RemoteHostIP+"\nport::"+RemotePort+"\ndata::"+SendInfStr);
System.out.println("确认收到信息,防止读卡器重复发送\n\n");
} catch (IOException e) {
System.out.println("发送失败: ");
e.printStackTrace();
}
//s1.close(); /**4、关闭资源*/
}
}
/*------------------------------------------------------------------------------------------------------------更改读卡器的IP、网关、掩码、服务器ip、端口等*/
static void SetNetworkPara(DatagramSocket s,byte[] data,int length,String RemoteHostIP,int RemotePort) throws Exception{
if(length>=38){
//DatagramSocket s1 = new DatagramSocket(); /** 1、建立udp socket端点 */
byte[] SendBuf1 = new byte [42]; /** 2、将要发送的数据打包 */
SendBuf1[0]=(byte)0xF9;
SendBuf1[1]=data[1]; //读卡器ip,如需修改设正确值
SendBuf1[2]=data[2];
SendBuf1[3]=data[3];
SendBuf1[4]=data[4];
SendBuf1[5]=data[5]; //读卡器子网掩码,如需修改设正确值
SendBuf1[6]=data[6];
SendBuf1[7]=data[7];
SendBuf1[8]=data[8];
SendBuf1[9]=(byte)0xff; //data[23]; //读卡器远程服务器IP,,255.255.255.255表示广播方式,如需修改设正确值
SendBuf1[10]=(byte)0xff; //data[24];
SendBuf1[11]=(byte)0xff; //data[25];
SendBuf1[12]=(byte)0xff; //data[26];
SendBuf1[13]=data[27]; //读卡器远程服务器IP MAC,取值FF-FF-FF-FF-FF-FF 表示自动搜索MAC
SendBuf1[14]=data[28];
SendBuf1[15]=data[29];
SendBuf1[16]=data[30];
SendBuf1[17]=data[31];
SendBuf1[18]=data[32];
SendBuf1[19]=data[13]; //读卡器网关IP,如需修改设正确值
SendBuf1[20]=data[14];
SendBuf1[21]=data[15];
SendBuf1[22]=data[16];
SendBuf1[23]=data[17]; //读卡器网关MAC,取值FF-FF-FF-FF-FF-FF 表示自动搜索MAC
SendBuf1[24]=data[18];
SendBuf1[25]=data[19];
SendBuf1[26]=data[20];
SendBuf1[27]=data[21];
SendBuf1[28]=data[22];
SendBuf1[29]=data[11]; //机号,如需修改设正确值
SendBuf1[30]=data[12];
SendBuf1[31]=data[9]; //通讯端口,如需修改设正确值
SendBuf1[32]=data[10];
SendBuf1[33]=data[35]; //机器序列号,每台机唯一,不可更改
SendBuf1[34]=data[36];
SendBuf1[35]=data[37];
SendBuf1[36]=data[38];
byte Funcode;
Funcode=1; //0 刷卡时不发声 1 刷卡时发声
Funcode=(byte)(Funcode+2); //+2 远程电脑MAC自动搜索 +4 网关MAC自动搜索
Funcode=(byte)(Funcode+8); //+8 DHCP自动获得IP地址 +0 指定IP
Funcode=(byte)(Funcode+0); //+16 卡离开感应区发信息 +0 卡离开感应区不发信息
Funcode=(byte)(Funcode+32*0); //卡在感应区是否重发信息 *0不重发 *1隔1秒重发 *2隔2秒重发 *3隔5秒重发 *4隔10秒重发
SendBuf1[37]=Funcode;
SendBuf1[38]=(byte)0x55; //4字节固定后缀
SendBuf1[39]=(byte)0xaa;
SendBuf1[40]=(byte)0x66;
SendBuf1[41]=(byte)0x99;
DatagramPacket dp1 = new DatagramPacket(SendBuf1, SendBuf1.length, InetAddress.getByName(RemoteHostIP), RemotePort);
try { /** 3、 发送数据 **/
s.send(dp1);
String SendInfStr=""; //将发送的信息显示
for(int p=0;p<42;p++){
String bytestr="00"+Integer.toHexString(SendBuf1[p] & 0xff);
SendInfStr=SendInfStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
System.out.println("SendTo ip::"+RemoteHostIP+"\nport::"+RemotePort+"\ndata::"+SendInfStr);
System.out.println("更改设备的网络参数\n\n");
} catch (IOException e) {
System.out.println("发送失败: ");
e.printStackTrace();
}
//s1.close(); /**4、关闭资源*/
}
}
/*---------------------------------------------------------------------------------------------------------------发指令到读写器读取指定扇区内数据*/
static void ReadCardInf(DatagramSocket s,byte[] data,int length,String RemoteHostIP,int RemotePort) throws Exception{
if(length>=8){
//DatagramSocket s1 = new DatagramSocket(); /** 1、建立udp socket端点 */
byte[] SendBuf1 = new byte [16]; /** 2、将要发送的数据打包 */
SendBuf1[0]=(byte)0x3B;
SendBuf1[1]=data[5]; //机号低
SendBuf1[2]=data[6]; //机号高,如高低都为0表示任意机号
SendBuf1[3]=(byte)0x01; //扇区个数
SendBuf1[4]=data[10]; //要操作的卡号,如4个字节都取0表示可操作任意卡
SendBuf1[5]=data[11];
SendBuf1[6]=data[12];
SendBuf1[7]=data[13];
SendBuf1[8]=(byte)0x08; //要读取的扇区号
SendBuf1[9]=(byte)0x00; //取值0表示以A密码认证,取值1表示以B密码认证
SendBuf1[10]=(byte)0xFF; //6字节的卡片认证密码
SendBuf1[11]=(byte)0xFF;
SendBuf1[12]=(byte)0xFF;
SendBuf1[13]=(byte)0xFF;
SendBuf1[14]=(byte)0xFF;
SendBuf1[15]=(byte)0xFF;
DatagramPacket dp1 = new DatagramPacket(SendBuf1, SendBuf1.length, InetAddress.getByName(RemoteHostIP), RemotePort);
try { /** 3、 发送数据 **/
s.send(dp1);
String SendInfStr="";
for(int p=0;p<16;p++){
String bytestr="00"+Integer.toHexString(SendBuf1[p] & 0xff);
SendInfStr=SendInfStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
System.out.println("SendTo ip::"+RemoteHostIP+"\nport::"+RemotePort+"\ndata::"+SendInfStr);
System.out.println("向读写器发送读取扇区信息的指令\n\n");
} catch (IOException e) {
System.out.println("发送失败: ");
e.printStackTrace();
}
//s1.close(); /**4、关闭资源*/
}
}
/*---------------------------------------------------------------------------------------------------------------发指令写数据到卡内*/
static void WriteCard(DatagramSocket s,byte[] data,int length,String RemoteHostIP,int RemotePort) throws Exception{
if(length>=62){
//DatagramSocket s1 = new DatagramSocket(); /** 1、建立udp socket端点 */
byte[] SendBuf1 = new byte [68]; /** 2、将要发送的数据打包 */
SendBuf1[0]=(byte)0x3D; //指定扇区写卡指令
SendBuf1[1]=data[5]; //机号低
SendBuf1[2]=data[6]; //机号高,如高低都为0表示任意机号
SendBuf1[3]=(byte)0x01; //扇区个数
SendBuf1[4]=data[8]; //要操作的卡号,如4个字节都取0表示可操作任意卡
SendBuf1[5]=data[9];
SendBuf1[6]=data[10];
SendBuf1[7]=data[11];
SendBuf1[8]=(byte)0x08; //要操作的扇区号
SendBuf1[9]=(byte)0x00; //取值0表示以A密码认证,取值1表示以B密码认证
SendBuf1[10]=(byte)0xFF; //6字节的卡片认证密码
SendBuf1[11]=(byte)0xFF;
SendBuf1[12]=(byte)0xFF;
SendBuf1[13]=(byte)0xFF;
SendBuf1[14]=(byte)0xFF;
SendBuf1[15]=(byte)0xFF;
for(int p=0;p<48;p++){ //48个字节的写入信息,一定要满48字节
SendBuf1[16+p]=data[14+p]; //这里表示将读出的信息重新写入,如要写新的数据将数据写入这段缓冲
}
SendBuf1[64]=(byte)0x55; //固定的抗干扰后缀
SendBuf1[65]=(byte)0xAA;
SendBuf1[66]=(byte)0x66;
SendBuf1[67]=(byte)0x99;
DatagramPacket dp1 = new DatagramPacket(SendBuf1, SendBuf1.length, InetAddress.getByName(RemoteHostIP), RemotePort);
try { /** 3、 发送数据 **/
s.send(dp1);
String SendInfStr="";
for(int p=0;p<68;p++){
String bytestr="00"+Integer.toHexString(SendBuf1[p] & 0xff);
SendInfStr=SendInfStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
}
System.out.println("SendTo ip::"+RemoteHostIP+"\nport::"+RemotePort+"\ndata::"+SendInfStr);
System.out.println("向读写器发送写扇区信息的指令\n\n");
} catch (IOException e) {
System.out.println("发送失败: ");
e.printStackTrace();
}
//s1.close(); /**4、关闭资源*/
}
}
/*---------------------------------------------------------------------------------------------------------判断字符串是不是一个日期时间格式*/
static boolean IsDateTime(String inputstr) {
Date date=null;
SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
date=formatter.parse(inputstr);
return true;
}catch (Exception e) {
return false;
}
}
/*--------------------------------------------------------------------------------------------------------------------取电脑系统日期时间*/
static String GetSysDT() {
Date date=new Date();
SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String TimeStr=formatter.format(date);
return TimeStr;
}
/*----------------------------------------------------------------------------------------------------------------------------取电脑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(1); //如有多张网卡,请选择与设备相连的网卡,否则无法与设备正常通讯
}
}
}
运行示例: