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項目,就可以接受客戶端過來的數據了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM