javaweb啟動(dòng)時(shí)啟動(dòng)socket服務(wù)端代碼實(shí)現(xiàn)
這篇文章主要介紹了javaweb啟動(dòng)時(shí)啟動(dòng)socket服務(wù)端代碼實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
說(shuō)明:在javaweb項(xiàng)目啟動(dòng)的時(shí)候啟動(dòng)socket服務(wù)端,可以接受客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù),客戶端可以反復(fù)斷開(kāi)連接
1.新建SocketThread線程類(lèi)
package com.wlw.modules.startImplement.web;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* socket 線程類(lèi)
* @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創(chuàng)建socket服務(wù)出錯(cuò)");
e.printStackTrace();
}
}
public void run(){
while(!this.isInterrupted()){
try {
Socket socket = serverSocket.accept();
if(null != socket && !socket.isClosed()){
//處理接受的數(shù)據(jù)
new SocketOperate(socket).start();
}
// socket.setSoTimeout(30000); //設(shè)置超時(shí)
}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,用于接受客戶端傳來(lái)的數(shù)據(jù)
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接收的數(shù)據(jù)
* @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]; // 一次讀取一個(gè)byte
String ret = "";
while (dis.read(bytes) != -1) {
ret += MessageParsing.bytesToHexString(bytes) + "";
if (dis.available() == 0) { //一個(gè)請(qǐng)求
System.out.println("轉(zhuǎn)換為字符串后:"+MessageParsing.hexStringToString(ret));
System.out.println("轉(zhuǎn)為map后的數(shù)據(jù):"+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項(xiàng)目啟動(dòng)的時(shí)候會(huì)執(zhí)行里面的方法,去啟動(dòng)socket,可以用串口調(diào)試工具測(cè)試
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
*/
//創(chuàng)建的類(lèi)名根據(jù)需要定義,但一定要實(shí)現(xiàn)ServletContextListener接口
public class InitJob implements ServletContextListener {
//socket server 線程
private SocketThread socketThread;
/**
* 項(xiàng)目在啟動(dòng)初始化的時(shí)候就會(huì)執(zhí)行的方法(啟動(dòng)服務(wù)時(shí)執(zhí)行)
* @param arg0
*/
@Override
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
//這里可以放你要執(zhí)行的代碼或方法
if(null==socketThread && "yes".equals(Global.getConfig("socket"))){
// MessageParsing.calculation();
//新建線程類(lèi)
socketThread=new SocketThread(null);
//啟動(dòng)線程
socketThread.start();
}
}
/**
*contextDestroyed是在消亡的時(shí)候執(zhí)行的方法(關(guān)閉服務(wù)時(shí)執(zhí)行)
* @param arg0
*/
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
if(null!=socketThread && !socketThread.isInterrupted()){
socketThread.closeSocketServer();
socketThread.interrupt();
}
}
}
4.這里需要一個(gè)報(bào)文解析工具類(lèi)
package com.wlw.modules.lhjh.socket.tstandard;
import java.util.HashMap;
import java.util.Map;
/**
* HJ/T212 報(bào)文解析
* @Author: zhouhe
* @Date: 2019/4/12 10:11
*/
public class MessageParsing {
/**
* 字符串轉(zhuǎn)換為 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[]數(shù)組轉(zhuǎn)換為16進(jìn)制的字符串
*
* @param bytes 要轉(zhuǎn)換的字節(jié)數(shù)組
* @return 轉(zhuǎn)換后的結(jié)果
*/
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進(jìn)制轉(zhuǎn)換成為string類(lèi)型字符串
* 這個(gè)方法中文會(huì)亂碼,字母和數(shù)字都不會(huì)亂碼
*
* @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;
}
}
這樣就大功告成了,啟動(dòng)web項(xiàng)目,就可以接受客戶端過(guò)來(lái)的數(shù)據(jù)了
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 基于java socket實(shí)現(xiàn) 聊天小程序
- 如何解決線程太多導(dǎo)致java socket連接池出現(xiàn)的問(wèn)題
- Java通過(guò)socket客戶端保持連接服務(wù)端實(shí)現(xiàn)代碼
- java與微信小程序?qū)崿F(xiàn)websocket長(zhǎng)連接
- java 實(shí)現(xiàn)websocket的兩種方式實(shí)例詳解
- java實(shí)現(xiàn)基于Tcp的socket聊天程序
- Java基于socket實(shí)現(xiàn)的客戶端和服務(wù)端通信功能完整實(shí)例
- JAVA socket.io注解原理及用法圖解
相關(guān)文章
Java getResource()如何獲取class文件目錄位置
這篇文章主要介紹了Java getResource()如何獲取class文件目錄位置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
mybatis-puls中的resultMap數(shù)據(jù)映射
這篇文章主要介紹了mybatis-puls中的resultMap數(shù)據(jù)映射,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Java 讀取類(lèi)路徑下的資源文件實(shí)現(xiàn)代碼
這篇文章主要介紹了Java 讀取類(lèi)路徑下的資源文件實(shí)現(xiàn)代碼的相關(guān)資料,主要實(shí)現(xiàn)工具類(lèi)代碼ResourceLoadUtil.java的實(shí)例需要的朋友可以參考下2017-07-07
Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用
這篇文章主要介紹了Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
Java 數(shù)據(jù)流之Broadcast State
這篇文章主要介紹了Java 數(shù)據(jù)流之Broadcast State,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
Spring boot啟動(dòng)流程之解決循環(huán)依賴的方法
循環(huán)依賴,指的是兩個(gè)bean之間相互依賴,形成了一個(gè)循環(huán),spring解決循環(huán)依賴的方式是在bean的實(shí)例化完成之后,所以不要在構(gòu)造方法中引入循環(huán)依賴,因?yàn)檫@時(shí)對(duì)象還沒(méi)有實(shí)例化,spring也無(wú)法解決,本文給大家介紹Spring boot循環(huán)依賴的解決方法,一起看看吧2024-02-02
Java?ClassLoader虛擬類(lèi)實(shí)現(xiàn)代碼熱替換的示例代碼
本文主要介紹了Java?ClassLoader虛擬類(lèi)實(shí)現(xiàn)代碼熱替換的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
mybatis 插件: 打印 sql 及其執(zhí)行時(shí)間實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇mybatis 插件: 打印 sql 及其執(zhí)行時(shí)間實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
JAVASE精密邏輯控制過(guò)程詳解(分支和循環(huán)語(yǔ)句)
在一個(gè)程序執(zhí)行的過(guò)程中各條語(yǔ)句的執(zhí)行順序?qū)Τ绦虻慕Y(jié)果是有直接影響的,這篇文章主要給大家介紹了關(guān)于JAVASE精密邏輯控制(分支和循環(huán)語(yǔ)句)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04

