socket服务器接收客户端传来的byte数组,并进行,相应的解析验证,最后用JDBC插入到数据库,相关代码如下
1.。服务端
package com.dr.SocketServer;
import java.util.ArrayList;
import java.util.List;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import javax.servlet.http.HttpServlet;
import org.apache.log4j.Logger;
import com.dr.common.DBHelper;
public class EchoServer1 implements Runnable {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* @param args
*/
private static List<String> insert_info_list;
// 测试数据
static byte[] tmp1 = { 0x01, (byte) 0xA4, 0x31, 0x74, 0x10, 0x21, 0x60,
0x00, 0x08, 0x34, 0x6D, 0x10, 0x21, 0x4E, 0x06, (byte) 0xDE, 0x22,
(byte) 0xD8, (byte) 0xB7, 0x61, 0x02, 0x76, 0x5F, (byte) 0xF0,
0x06, 0x00, (byte) 0xA0, 0x48, (byte) 0xC0, 0x05, 0x00, 0x06, 0x10,
0x24, 0x00, 0x1A, (byte) 0xBD, 0x0B, 0x12, 0x10, 0x31, 0x00, 0x00,
0x0F, 0x06, 0x10, 0x24, 0x00, 0x00, 0x00, (byte) 0xF0, 0x64, 0x00,
0x00, (byte) 0xB4, 0x10, 0x30, (byte) 0x95, 0x29, (byte) 0xC6,
0x31, 0x04 };
private static final Logger log = Logger.getLogger(EchoServer1.class);
public static void main(String[] args) {
EchoServer1 e = new EchoServer1();
Thread td = new Thread(e);
td.start();
}
/**********************************************************************
* 函数名称:run 功能:线程运行主函数。 参数:null 返回:null 作者:wty 编辑时间:20120828
* ********************************************************************/
public void run() {
ServerSocket server = null;
//PrintStream out = null;
BufferedInputStream buf = null;
byte[] tmp = new byte[1024];
//SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Socket client = null;
try {
server = new ServerSocket(86);
while (true) {
// 监听socket
client = server.accept();
System.out.println("有客户端连接");
//out = new PrintStream(client.getOutputStream());
buf = new BufferedInputStream(client.getInputStream());
while (true) {
// 读取socket数据
buf.read(tmp);
System.out.println("接收数据:" + tmp);
// 判断接收数据开始位置
if (tmp[0] != 0x01) {
log.info(bytetostring(tmp));
break;
}
// 判断结束数据指令
if (tmp[2] != 0x31) {
log.info(bytetostring(tmp));
break;
}
// CRC校验
// byte[] newByte = subBytes(tmp, 1, tmp.length - 4);
// String crc = crcTable(newByte);
// String crcRe = result.substring(result.length() - 4,
// result.length() - 2);
// if (crc != crcRe) {
// log.info(bytetostring(tmp));
// break;
// }
// 解析指令
ProcessMessage(tmp);
// 数据入库
insertOrder();
// 调用接口
// 打印数据处理日志
log.info(bytetostring(tmp));
break;
}
break;
// out.close();
// buf.close();
// client.close();
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**********************************************************************
* 函数名称:subBytes 功能:按位置取子bytes。 参数:原始byte数组,begin起始位置,count長度 返回:子bytes 作者:
* 编辑时间:20120828
* ********************************************************************/
public byte[] subBytes(byte[] src, int begin, int count) {
byte[] bs = new byte[count];
for (int i = begin; i < begin + count; i++)
bs[i - begin] = src[i];
return bs;
}
/**********************************************************************
* 函数名称:bytetostring 功能:将byte类型数据转换为16进制字符串形式。 参数:原始byte数组 返回:转换后的16进制字符串
* 作者:wty 编辑时间:20120828
* ********************************************************************/
public String bytetostring(byte[] src_bytes) {
String byte_string = "";
for (int i = 0; i < src_bytes.length; i++) {
if (src_bytes[i] != 0) {
byte_string += Integer.toString((src_bytes[i] & 0xff) + 0x100,
16).substring(1)
+ " ";
if (src_bytes[i] == 0x04) {
break;
}
}
}
byte_string = byte_string.toUpperCase();
return byte_string;
}
/**********************************************************************
* 函数名称:insertOrder 功能:将解析后的设备信息存储到数据库 参数:NULL 返回:null 作者: 编辑时间:20120828
* ********************************************************************/
public int insertOrder() throws Exception {
java.sql.PreparedStatement ps = null;
java.sql.ResultSet rs = null;
java.sql.Connection conn = null;
Date d = new Date();
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
conn = DBHelper.getConn();
ps = conn
.prepareStatement("insert into orderinfo (orderid, EQUIPMENTID,LATITUDE,LONGITUDE,SPEED,state, curtime) values(?, ?, ?,?,?,?,?)");
Long seq_order_info = getAminList();
ps.setLong(1, seq_order_info);
ps.setLong(2, Integer.parseInt(insert_info_list.get(0)));
ps.setLong(3, Integer.parseInt(insert_info_list.get(2)));
ps.setLong(4, Integer.parseInt(insert_info_list.get(3)));
ps.setLong(5, Integer.parseInt(insert_info_list.get(4)));
ps.setLong(6, 0);
ps.setTimestamp(7, new Timestamp(d.getTime()));
System.out.print(ps);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
return 0;
} finally {
DBHelper.closeAll(rs, ps, conn);
}
return 1;
}
/**********************************************************************
* 函数名称:getAminList 功能:获取order_info的序列。 参数:NULL 返回:null 作者: 编辑时间:20120828
* ********************************************************************/
public Long getAminList() {
java.sql.PreparedStatement ps = null;
java.sql.ResultSet rs = null;
java.sql.Connection conn = null;
conn = DBHelper.getConn();
Long n = 0L;
String sql = "select seq_orderinfo.nextval from dual";
try {
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
n = rs.getLong(1);
}
return n;
} catch (SQLException e) {
e.printStackTrace();
}
return n;
}
/**********************************************************************
* 函数名称:crcTable 功能:CRC16计算程序 参数:原始bytes 返回:crc值 作者: 编辑时间:20120828
* ********************************************************************/
public static String crcTable(byte[] bytes) {
int[] table = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280,
0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481,
0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81,
0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880,
0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81,
0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80,
0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680,
0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081,
0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281,
0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480,
0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80,
0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881,
0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80,
0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81,
0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681,
0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080,
0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281,
0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480,
0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80,
0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881,
0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80,
0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81,
0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681,
0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080,
0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280,
0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481,
0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81,
0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880,
0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81,
0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80,
0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680,
0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081,
0x4040, };
int crc = 0xffff; // 初始化crc值
for (byte b : bytes) {
crc = (crc >>> 8) ^ table[(crc ^ b) & 0xff];
}
return Integer.toHexString(crc);
}
/**********************************************************************
* 函数名称:ProcessMessage 功能:设备数据信息解析程序 参数:原始设备数据bytes 返回: null 作者:
* 编辑时间:20120828
* ********************************************************************/
public static void ProcessMessage(byte[] tmp) {
byte[] temp = new byte[1024];
byte[] temp1 = new byte[4];
// 清理掩码信息
temp = updatemarks(tmp);
insert_info_list = new ArrayList<String>();
// 解析設備ID
for (int i = 0; i < 4; i++) {
temp1[i] = temp[i + 3];
}
Integer driver_id = Integer.valueOf(getINTFromByte(temp1));
insert_info_list.add(0, driver_id.toString());
// 解析日期
temp1 = new byte[4];
for (int i = 0; i < 4; i++) {
temp1[i] = temp[i + 11];
}
Integer date_number = Integer.valueOf(getINTFromByte(temp1));
insert_info_list.add(1, date_number.toString());
// 解析經度
temp1 = new byte[4];
for (int i = 0; i < 4; i++) {
temp1[i] = temp[i + 15];
}
Integer latitude = Integer.valueOf(getINTFromByte(temp1));
insert_info_list.add(2, latitude.toString());
// 解析緯度
temp1 = new byte[4];
for (int i = 0; i < 4; i++) {
temp1[i] = temp[i + 19];
}
Integer longitude = Integer.valueOf(getINTFromByte(temp1));
insert_info_list.add(3, longitude.toString());
// 解析速度
temp1 = new byte[10];
for (int i = 0; i < 1; i++) {
temp1[i] = temp[i + 27];
}
Integer speed = Integer.valueOf(temp1[0]);
insert_info_list.add(4, speed.toString());
}
/**********************************************************************
* 函数名称:updatemarks 功能:处理数据中掩码信息 参数:原始设备数据bytes 返回: null 作者: 编辑时间:20120828
* ********************************************************************/
public static byte[] updatemarks(byte[] tmp) {
byte[] temp = new byte[1024];
int j = 0;
for (int i = 0; i < tmp.length; i++) {
if (tmp[i] == 0x10) {
switch (tmp[i + 1]) {
case 0x21:
temp[i - j] = 0x01;
break;
case 0x24:
temp[i - j] = 0x04;
break;
case 0x30:
temp[i - j] = 0x10;
break;
case 0x31:
temp[i - j] = 0x11;
break;
case 0x33:
temp[i - j] = 0x13;
break;
}
i++;
j++;
} else {
temp[i - j] = tmp[i];
}
}
String result = "";
for (int i = 0; i < temp.length; i++) {
result += Integer.toString((temp[i] & 0xff) + 0x100, 16).substring(
1)
+ " ";
}
System.out.println(result);
return temp;
}
/**********************************************************************
* 函数名称:getINTFromByte 功能:将4自己byte转换为int类型 注:该函数转换的byte是低字节再前。 参数:原始bytes
* 返回: 转换后的int类型数据 作者: 编辑时间:20120828
* ********************************************************************/
public static int getINTFromByte(byte[] buffer) {
int a = 0;
a = (0xff000000 & (((int) buffer[3]) << 24) | 0x00ff0000
& (((int) buffer[2]) << 16) | 0x0000ff00
& (((int) buffer[1]) << 8) | 0x000000ff & (((int) buffer[0]) << 0));
return a;
}
}
2.测试的客户端
package com.dr.SocketServer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class EchoClient {
/**
* @param args
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
Socket client = null;
BufferedReader buf = null;
PrintStream out = null;
//System.out.println("准备连接服务器");
// client = new Socket("121.52.216.217",86);
client = new Socket("localhost",86);
buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
/*System.out.println(buf.readLine());
System.out.println(buf.readLine());*/
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String userInput = null;
out = new PrintStream(client.getOutputStream());
byte[] b ={
0x01, (byte)0xA4, 0x31, 0x74, 0x10, 0x21, 0x60, 0x00, 0x08, 0x34, 0x6D, 0x10, 0x21, 0x4E, 0x06, (byte)0xDE,
0x22, (byte)0xD8, (byte)0xB7, 0x61, 0x02, 0x76, 0x5F, (byte)0xF0, 0x06, 0x00, (byte)0xA0, 0x48, (byte)0xC0, 0x05, 0x00, 0x06,
0x10, 0x24, 0x00, 0x1A, (byte)0xBD, 0x0B, 0x12, 0x10, 0x31, 0x00, 0x00, 0x0F, 0x06, 0x10, 0x24, 0x00,
0x00, 0x00, (byte)0xF0, 0x64, 0x00, 0x00, (byte)0xB4, 0x10, 0x30, (byte)0x95, 0x29, (byte)0xC6, 0x31, 0x04
};
while((userInput = in.readLine())!=null){
String str="";
//转化为16进制,在当地看,传过去的还是在控制台直接输入的
for (int i=0;i<userInput.length();i++)
{
int ch = (int)userInput.charAt(i);
String s4 = Integer.toHexString(ch);
str = str + s4;
}
out.println(userInput);
System.out.println(str);
}
out.close();
in.close();
client.close();
}
}