Socket编程

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();
         
         
	}

}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值