1. 程式人生 > 程式設計 >javaweb啟動時啟動socket服務端程式碼實現

javaweb啟動時啟動socket服務端程式碼實現

這篇文章主要介紹了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專案,就可以接受客戶端過來的資料了

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。