// QQ:954486673
//微信:13822155058
//淘宝:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-17663462238.11.12cd5b43ejf7s9&id=17029933847
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、关闭资源
//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<length;p++){ bytestr="00"+Integer.toHexString(data[p] & 0xff); 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<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"); 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 (int j=28; j>=0; j-=4) { cardno10 = cardno10<<4 | (cardnum>>>j & 0xF); } CardNoStr = String.format("0d", 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(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("0d", 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(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<NetworkInterface> netInterfaces; String ipaddstr=""; 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) { System.out.println(ni.getName() + " " + ip.getHostAddress()); if(ipaddstr.length()==0){ ipaddstr=ip.getHostAddress(); } } } } } catch (Exception e) { } return ipaddstr; } }
运行示例: