package com.jxkj.udp.server;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.jxkj.util.Util;
/**
* 接收UDP数据
* @author sourcezero
*
*/
public class UdpServer {
private static Logger logger = Logger.getLogger(UdpServer.class);
private static int port = 9999;
public static byte start_flag = (byte) 0x68;
public static void main(String[] args) {
DatagramSocket ds = null;
try {
if(args!=null&&args.length>0){
port = Integer.valueOf(args[0]);
}
logger.info("开始监听端口 " + port + " 的数据...");
InetAddress addr = InetAddress.getLocalHost();
InetSocketAddress socketAddress = new InetSocketAddress(port);
ds = new DatagramSocket(socketAddress);
logger.info("主机名:" + addr.getHostName() + ", ip地址:" + addr.getHostAddress());
//ds.setSoTimeout(600 * 1000);
ds.setSoTimeout( 3000);//阻塞等待时长
while (true) {
byte[] buffer = new byte[65*1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try{
ds.receive(packet);// 17313 3072
logger.info("接收到来自ip:"+packet.getAddress()+",端口为"+packet.getPort()+"的数据");
byte[] data = packet.getData();
if(data.length>0){
List<byte[]> list = splitMessage(data);
for (byte[] bs : list) {
String content = Util.hexDecode(hex2String(toHexString(bs)));
System.out.println(content);
}
}
}catch(SocketTimeoutException ste){
//logger.error("接收UDP数据超时...");
}catch(Exception e){
logger.error("接收UDP出错...",e);
}
}
} catch (IOException e) {
logger.error(e);
}finally{
if(ds!=null){
ds.close();
}
}
}
public static String hex2String(String hex) {
StringBuilder sb = new StringBuilder();
StringBuilder temp = new StringBuilder();
// 49204c6f7665204a617661 split into two characters 49, 20, 4c...
for (int i = 0; i < hex.length() - 1; i += 2) {
// grab the hex in pairs
String output = hex.substring(i, (i + 2));
// convert hex to decimal
int decimal = Integer.parseInt(output, 16);
// convert the decimal to character
sb.append((char) decimal);
temp.append(decimal);
}
return sb.toString();
}
public static String toHexString(byte[] buf) {
String hex = "";
if (buf == null)
return hex;
for (int i = 0; i < buf.length; i++) {
hex += toHexString(buf[i]);
}
return hex;
}
public static List<byte[]> splitMessage(byte[] message) {
List<byte[]> list = new ArrayList<byte[]>();
int len = 0;
for (int i = 0; i < message.length;) {
// 以68为标识进行切分
if (message[i] == start_flag) {
// 发送站端地址
logger.debug("发送站端地址:"
+ asUnsignedByte(message[1]));
// 报文长度
len = valueOf2byte(message[i + 2],message[i + 3]);
logger.debug("报文长度:"+len);
if (len > 0) {
byte[] submessage = new byte[len];
for (int k = 0; k < len; k++) {
int tmp =11+k;
submessage[k] = message[tmp];
}
list.add(submessage);
// 校验码为unsigned short类型,生成方式为从启动字符开始至报文体结束的unsigned char
// 的算术累加和,进位位丢弃。
// log.debug("校验码:"+ByteUtil.bytesToShort(message,len+4));
i += len + 11;
}
}
i++;
}
return list;
}
/**
* @param hight 高位
* @param low 低位
* @return int
*/
public static int valueOf2byte(byte low, byte hight) {
String value = toHexString(low) + toHexString(hight);
return Integer.parseInt(value, 16);
}
public static int asUnsignedByte(byte b) {
return Integer.parseInt(toHexString(b), 16);
}
/**
* 将字节转换为用16进表示的字符串
*
* @param buf
* byte
* @return String
*/
public static String toHexString(byte b) {
String s = Integer.toHexString(b);
if (s.length() == 1) {
s = "0" + s;
} else if (s.length() > 2) {
s = s.substring(s.length() - 2);
}
return s;
}
public static byte[] addBytes(byte[] data1, byte[] data2) {
byte[] data3 = new byte[data1.length + data2.length];
System.arraycopy(data1, 0, data3, 0, data1.length);
System.arraycopy(data2, 0, data3, data1.length, data2.length);
return data3;
}
}