zoukankan      html  css  js  c++  java
  • javaweb启动时启动socket服务端

    说明:在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项目,就可以接受客户端过来的数据了

  • 相关阅读:
    代码整洁之道
    PHP并发IO编程之路
    U盘启动盘的制作--用U盘硬装Windows系统、或是重装Windows系统
    Navicat for MySQL11--使用经验
    Eclipse字体颜色的设置方法
    5.5树和森林
    5.2二叉树
    3.3队列
    3.1栈
    2.3线性表的链式存储结构
  • 原文地址:https://www.cnblogs.com/zhouheblog/p/11245833.html
Copyright © 2011-2022 走看看