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.net.DatagramPacket;
import java.net.DatagramSocket;
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、关闭资源
//udp通讯: 发送
// 1、建立udp socket 端点
// 2、将要发送的数打包封装
/ /3、使用send发送数据
// 4、关闭资源
public class UdpRecv {
public static void main(String[] args) throws Exception{
String MyIpAdd=getIP();
System.out.println("当前软件绑定的网卡:"+MyIpAdd+"\n\n");
DatagramSocket s = new DatagramSocket(39169); /** 1、建立udp socket端点 */
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 [] LastBuf =new byte[9]; /** 用于保存最后上传的信息*/
boolean i=true;
while(i){
int p=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="";
long cardno10;
long cardnum;
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(data,length,RemoteHostIP,RemotePort); //向读卡器发确认信息,否则读卡器会连续发三次
// 重复的上传的数据不分析处理,直接丢弃
}else{
for(p=0;p
ReceiveDataStr=ReceiveDataStr+ bytestr.substring(bytestr.length() -2,bytestr.length())+" ";
if(p<9){ /*将当前接收到的数据保存,用于再次接收到数据时比对*/
LastBuf[p]=data[p];
}
}
System.out.println("From ip::"+rdp.getAddress().getHostAddress()+"\nport::"+rdp.getPort()+"\ndata::"+ReceiveDataStr);
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[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);
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
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("设备唯一序号:"+SerialNum);
}
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
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 (int 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
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("设备序列号:"+SerialNum+"\n\n");
DisableSendAge(data,length,RemoteHostIP,RemotePort); //向读卡器发确认信息,否则读卡器会连续发三次
SendDispBeep(CardNoStr,RemoteHostIP,RemotePort); //发送显示及声音
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(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 (int 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
SerialNum=SerialNum+ bytestr.substring(bytestr.length() -2,bytestr.length());
}
System.out.println("设备序列号:"+SerialNum);
System.out.println("\n\n");
DisableSendAge(data,length,RemoteHostIP,RemotePort); //向读卡器发确认信息,否则读卡器会连续发三次
SendDispBeep(CardNoStr,RemoteHostIP,RemotePort); //发送显示及声音
break;
default:
}
}
}
}
s.close(); /**5、关闭资源*/
}
/*--------------------------------------------------------------------------------------------------------------------------------*/
static void SendDispBeep(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();
byte[] SendBuf1 = new byte [39]; /** 2、将要发送的数据打包 */
SendBuf1[0]=(byte)0x5a; //指令码
SendBuf1[1]=(byte)0x00; //机号低
SendBuf1[2]=(byte)0x00; //机号高
SendBuf1[3]=(byte)0x02; //蜂鸣声代码
SendBuf1[4]=(byte)0x14; //显示时长
for(int i=0;i<34;i++){
SendBuf1[i+5]=DispBuf[i];
}
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())+" ";
}
DatagramPacket dp1 = new DatagramPacket(SendBuf1, SendBuf1.length, InetAddress.getByName(RemoteHostIP), RemotePort);
try { /** 3、 发送数据 **/
s1.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、关闭资源*/
}
/*--------------------------------------------------------------------------------------------------------------------------------*/
static void DisableSendAge(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、 发送数据 **/
s1.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、关闭资源*/
}
}
/*---------------------------------------------------------------------------------------------------------判断字符串是不是一个日期时间格式*/
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
String ipaddstr="";
try {
netInterfaces = NetworkInterface.getNetworkInterfaces(); // 拿到所有网卡
InetAddress ip;
while (netInterfaces.hasMoreElements()) {
NetworkInterface ni = netInterfaces.nextElement();
Enumeration
while (addresses.hasMoreElements()) {
ip = addresses.nextElement();
if (!ip.isLoopbackAddress() && ip.getHostAddress().indexOf(':') == -1) {
System.out.println(ni.getName() + " " + ip.getHostAddress());
if(ipaddstr.length()==0){
ipaddstr=ip.getHostAddress();
}
}
}
}
} catch (Exception e) {
}
return ipaddstr;
}
}
运行示例: