javaweb启动时启动socket服务端代码实现

 更新时间:2019年11月28日 10:42:58   作者:农名工进城  
这篇文章主要介绍了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项目,就可以接受客户端过来的数据了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java getResource()如何获取class文件目录位置

    Java getResource()如何获取class文件目录位置

    这篇文章主要介绍了Java getResource()如何获取class文件目录位置,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • mybatis-puls中的resultMap数据映射

    mybatis-puls中的resultMap数据映射

    这篇文章主要介绍了mybatis-puls中的resultMap数据映射,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java 读取类路径下的资源文件实现代码

    Java 读取类路径下的资源文件实现代码

    这篇文章主要介绍了Java 读取类路径下的资源文件实现代码的相关资料,主要实现工具类代码ResourceLoadUtil.java的实例需要的朋友可以参考下
    2017-07-07
  • Java中static修饰的静态变量、方法及代码块的特性与使用

    Java中static修饰的静态变量、方法及代码块的特性与使用

    这篇文章主要介绍了Java中static修饰的静态变量、方法及代码块的特性与使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Java 数据流之Broadcast State

    Java 数据流之Broadcast State

    这篇文章主要介绍了Java 数据流之Broadcast State,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Spring boot启动流程之解决循环依赖的方法

    Spring boot启动流程之解决循环依赖的方法

    循环依赖,指的是两个bean之间相互依赖,形成了一个循环,spring解决循环依赖的方式是在bean的实例化完成之后,所以不要在构造方法中引入循环依赖,因为这时对象还没有实例化,spring也无法解决,本文给大家介绍Spring boot循环依赖的解决方法,一起看看吧
    2024-02-02
  • Java ClassLoader虚拟类实现代码热替换的示例代码

    Java ClassLoader虚拟类实现代码热替换的示例代码

    本文主要介绍了Java ClassLoader虚拟类实现代码热替换的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 详解Spring Retry实现原理

    详解Spring Retry实现原理

    这篇文章主要介绍了详解Spring Retry实现原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • mybatis 插件: 打印 sql 及其执行时间实现方法

    mybatis 插件: 打印 sql 及其执行时间实现方法

    下面小编就为大家带来一篇mybatis 插件: 打印 sql 及其执行时间实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • JAVASE精密逻辑控制过程详解(分支和循环语句)

    JAVASE精密逻辑控制过程详解(分支和循环语句)

    在一个程序执行的过程中各条语句的执行顺序对程序的结果是有直接影响的,这篇文章主要给大家介绍了关于JAVASE精密逻辑控制(分支和循环语句)的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-04-04

最新评论