1.创建ServletContextListener 监听器
package com.chinalbs.common.utils;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.chinalbs.business.service.EnvironprotectRealtimeDataService;
public class EquipmentSocetListener implements ServletContextListener {
private SocketThread socketThread;
@Override
public void contextInitialized(ServletContextEvent sce) {
EnvironprotectRealtimeDataService erdService = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()).getBean(EnvironprotectRealtimeDataService.class);
if (null == socketThread) {
// 新建线程类
socketThread = new SocketThread(null,erdService);
// 启动线程
socketThread.start();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
if (null != socketThread && !socketThread.isInterrupted()) {
socketThread.closeSocketServer();
socketThread.interrupt();
}
}
}
erdService 是后面需要进行具体业务处理的service实例,SocketThread类是自定义的线程类
2.SocketThread线程类代码
package com.chinalbs.common.utils;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import com.chinalbs.business.service.EnvironprotectRealtimeDataService;
public class SocketThread extends Thread {
private ServerSocket serverSocket = null;
private static final int PORT = 9092;
private EnvironprotectRealtimeDataService erdService;
public SocketThread(ServerSocket serverScoket,EnvironprotectRealtimeDataService erdService) {
this.erdService = erdService;
try {
if (null == serverSocket) {
this.serverSocket = new ServerSocket(PORT);
System.out.println("socket start");
}
} catch (Exception e) {
System.out.println("SocketThread创建socket服务出错");
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
if (serverSocket == null) {
break;
} else if (serverSocket.isClosed()) {
break;
}
Socket socket = serverSocket.accept();
if (null != socket && !socket.isClosed()) {
// 处理接收的数据
Thread t1 = new Thread(new SocketOperate(socket,erdService));
t1.start();
} else {
break;
}
} catch (Exception e) {
System.out.println("SocketThread创建socket服务出错111111111111111111111111");
e.printStackTrace();
}
}
}
public void closeSocketServer() {
try {
if (null != serverSocket && !serverSocket.isClosed()) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
SocketOperate是自定义的socket具体业务操作类
3.SocketOperate代码
package com.chinalbs.common.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import org.apache.commons.lang.ArrayUtils;
import com.chinalbs.business.model.EnvironprotectRealtimeData;
import com.chinalbs.business.service.EnvironprotectRealtimeDataService;
import net.sf.json.JSONObject;
public class SocketOperate implements Runnable {
private EnvironprotectRealtimeDataService erdService;
private Socket socket;
// 该线程所处理的Socket所对应的输入流
BufferedReader br = null;
String str = null;
String content = null;
InputStreamReader reader = null;
public SocketOperate(Socket socket,EnvironprotectRealtimeDataService erdService) throws IOException {
this.socket = socket;
this.erdService = erdService;
reader = new InputStreamReader(this.socket.getInputStream(), "GBK");
br = new BufferedReader(reader);
}
@Override
public void run() {
try {
// 采用循环不断从Socket中读取客户端发送过来的数据
while (true) {
content = readFromClient();
System.out.println(content);
if (content == null) {
//重发,或者什么都不做
break;
}else{
//验证接受到的信息是否正确,判断校验码是否一致
//一致,响应信息,插入数据
OutputStream os = socket.getOutputStream();
String responseStr = dataHandler(content);
os.write(responseStr.getBytes());
os.flush();
//不一致,重发或者什么都不做
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
//数据处理
private String dataHandler(String data){
//此处需要返回具体的应答数据,具体的数据格式,根据具体的业务要求
}
// 定义读取客户端数据的方法
private String readFromClient() {
try {
str = br.readLine();
return str;
}
// 如果捕捉到异常,表明该Socket对应的客户端已经关闭
catch (IOException e) {
try {
br.close();
reader.close();
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return null;
}
}
4.配置web.xml
5.将项目运行起来后可以查看器端口监听情况,这里监听的端口是9092,在window下,可以使用命令 netstat -aon|findstr "9092",在linux下可以使用命令netstat -tunlp|grep 9092
具体项目源码请参考https://download.csdn.net/download/jinxiumeihappy/12115422