说明:在javaweb项目启动的时候启动socket服务端,可以接受客户端发送过来的数据,客户端可以反复断开连接
1.新建SocketThread线程类
package com.wlw.modules.startImplement.web; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * socket 线程类 * @Author: zhouhe * @Date: 2019/4/16 14:58 */ public class SocketThread extends Thread { private ServerSocket serverSocket = null; public SocketThread(ServerSocket serverScoket){ try { if(null == serverSocket){ this.serverSocket = new ServerSocket(8877); System.out.println("socket start"); } } catch (Exception e) { System.out.println("SocketThread创建socket服务出错"); e.printStackTrace(); } } public void run(){ while(!this.isInterrupted()){ try { Socket socket = serverSocket.accept(); if(null != socket && !socket.isClosed()){ //处理接受的数据 new SocketOperate(socket).start(); } // socket.setSoTimeout(30000); //设置超时 }catch (Exception e) { } } } public void closeSocketServer(){ try { if(null!=serverSocket && !serverSocket.isClosed()) { serverSocket.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2.新建SocketOperate,用于接受客户端传来的数据
package com.wlw.modules.startImplement.web; import com.wlw.modules.lhjh.socket.tstandard.MessageParsing; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.IOException; import java.net.Socket; /** * 多线程处理socket接收的数据 * @Author: zhouhe * @Date: 2019/4/16 14:59 */ public class SocketOperate extends Thread { private Socket socket; public SocketOperate(Socket socket) { this.socket=socket; } @Override public void run() { try { //封装输入流(接收客户端的流) BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); DataInputStream dis = new DataInputStream(bis); byte[] bytes = new byte[1]; // 一次读取一个byte String ret = ""; while (dis.read(bytes) != -1) { ret += MessageParsing.bytesToHexString(bytes) + ""; if (dis.available() == 0) { //一个请求 System.out.println("转换为字符串后:"+MessageParsing.hexStringToString(ret)); System.out.println("转为map后的数据:"+MessageParsing.stringToMap(MessageParsing.hexStringToString(ret))); ret = ""; } } } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("client is over"); if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
3.新建InitJob,web项目启动的时候会执行里面的方法,去启动socket,可以用串口调试工具测试
package com.wlw.modules.startImplement.web; import com.wlw.common.config.Global; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; /** * @Author: zhouhe * @Date: 2019/4/16 11:00 */ //创建的类名根据需要定义,但一定要实现ServletContextListener接口 public class InitJob implements ServletContextListener { //socket server 线程 private SocketThread socketThread; /** * 项目在启动初始化的时候就会执行的方法(启动服务时执行) * @param arg0 */ @Override public void contextInitialized(ServletContextEvent arg0) { // TODO Auto-generated method stub //这里可以放你要执行的代码或方法 if(null==socketThread && "yes".equals(Global.getConfig("socket"))){ // MessageParsing.calculation(); //新建线程类 socketThread=new SocketThread(null); //启动线程 socketThread.start(); } } /** *contextDestroyed是在消亡的时候执行的方法(关闭服务时执行) * @param arg0 */ @Override public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub if(null!=socketThread && !socketThread.isInterrupted()){ socketThread.closeSocketServer(); socketThread.interrupt(); } } }
4.这里需要一个报文解析工具类
package com.wlw.modules.lhjh.socket.tstandard; import java.util.HashMap; import java.util.Map; /** * HJ/T212 报文解析 * @Author: zhouhe * @Date: 2019/4/12 10:11 */ public class MessageParsing { /** * 字符串转换为 map * @param arr * @return */ public static Map stringToMap(String arr){ arr=arr.replaceAll(",",";"); Map map = new HashMap(); if (null != arr) { String[] param = arr.split(";"); for (int i = 0; i < param.length; i++) { //这里的 index 要 >-1 才是 map格式 int index = param[i].indexOf('='); if(index>-1) map.put(param[i].substring(0,index), param[i].substring((index + 1))); } } return map; } /** * byte[]数组转换为16进制的字符串 * * @param bytes 要转换的字节数组 * @return 转换后的结果 */ public static String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(0xFF & bytes[i]); if (hex.length() == 1) { sb.append('0'); } sb.append(hex); } return sb.toString(); } /** * 16进制转换成为string类型字符串 * 这个方法中文会乱码,字母和数字都不会乱码 * * @Author zhouhe * @param s * @return */ public static String hexStringToString(String s) { if (s == null || s.equals("")) { return null; } s = s.replace(" ", ""); byte[] baKeyword = new byte[s.length() / 2]; for (int i = 0; i < baKeyword.length; i++) { try { baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16)); } catch (Exception e) { e.printStackTrace(); } } try { s = new String(baKeyword, "UTF-8"); new String(); } catch (Exception e1) { e1.printStackTrace(); } return s; } }
这样就大功告成了,启动web项目,就可以接受客户端过来的数据了