在项目中有需求,去监听tcp端口接收数据包,我实现如下:
1.完成监听操作,可单启一个线程来监听,实现思路差不多
SpringBoot Application支持6种事件监听:
ApplicationStartingEvent:在Spring最开始启动的时候触发
ApplicationEnvironmentPreparedEvent:在Spring已经准备好上下文但是上下文尚未创建的时候触发
ApplicationPreparedEvent:在Bean定义加载之后、刷新上下文之前触发
ApplicationStartedEvent. :在刷新上下文之后、调用application命令之前触发
ApplicationReadyEvent. :在调用applicaiton命令之后触发
ApplicationFailedEvent :在启动Spring发生异常时触发
让被监听的类implements ApplicationListener 重写其中的方法
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
System.err.println("启动了");
Thread yourThread = new Thread(() -> {
try {
//具体的方法执行部分;
} catch (IOException e) {
throw new RuntimeException(e);
}
});
yourThread.start();
}
2.实现
//其中post是被监听的端口
@Value(""${post})
private int post;
ServerSocket serverSocket = new ServerSocket(post);
监听端口接收数据包
while (true) {
try {
log.info("已成功监听到端口");
//没有数据包时,accept会一直阻塞在这部分
Socket clientSocket = serverSocket.accept();
//通过socket拿到相应的输入流和输出流,不需要相应时,输出流可删除
InputStream inputStream = clientSocket.getInputStream();
outputStream = clientSocket.getOutputStream();
//定义字节数据(具体长度自定义)
byte[] buffer = new byte[1024];
int len = inputStream.read(buffer);
//拿到具体的数据信息
String receivedMessage = new String(buffer, 0, len);
//拿到数据信息后处理
。。。。
//最终拿到返回的数据;
String response="";
//处理结束后
outputStream.write(response.getBytes());
inputStream.close();
outputStream.close();
clientSocket.close();
// serverSocket.close();
// 线程休眠一段时间,以避免过多占用 CPU
Thread.sleep(1000);
}catch(Exception e){
//以及异常处理需要的逻辑
}
}
发送数据包
这部分我使用了异步处理,可按需加或者删除
@Resource(name = "taskExecutor")
private ThreadPoolTaskExecutor threadPool;
/**
*其中file时我异常返回相应的错误信息,可根据需求调整
*sendMessage1方法是具体的逻辑
*/
public Element sendMessage(String s) {
//region 设置等待时常超时异步处理
CompletableFuture<Element> future = CompletableFuture.supplyAsync(() -> {
try {
return this.sendMessage1(s);
} catch (Exception e) {
log.error("OrderServiceImpl.sendEsb.error" + e);
Element response = this.file("999999", "异步响应处理错误");
return response; // 返回适当的默认值或错误处理
}
}, threadPool);
try {
return future.get(5, TimeUnit.SECONDS); // 等待异步任务完成,设置适当的超时时间
} catch (Exception e) {
log.error("OrderServiceImpl.sendEsb.error" + e);
Element response = this.file("999999", "异步响应超时");
return response; // 返回适当的默认值或错误处理
}
//endregion
}
/**
*其中设置了重试机制MAX_RETRY_COUNT
*/
public org.dom4j.Element sendMessage1(String xml) {
int retryCount = 0;
boolean success = false;
Element rootElement = null;
while (!success && retryCount < MAX_RETRY_COUNT) {
retryCount++;
try{
Socket socket = new Socket(lockIp, lockPost);
//设置超时处理
socket.setSoTimeout(TIMEOUT);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
//发送相应数据包
outputStream.write(xml.getBytes());
// 读取服务器发送的响应
byte[] buffer = new byte[1024];
int len = inputStream.read(buffer);
//接收到响应数据,响应部分无需要可删除
String receivedMessage = new String(buffer, 0, len);
outputStream.close();
inputStream.close();
socket.close();
// 操作成功,跳出循环
success = true;
}catch (Exception e){
log.error("发送xml异常"+e);
if (retryCount < MAX_RETRY_COUNT) {
log.info("进行第 " + retryCount + " 次重试");
} else {
log.error("已达到最大重试次数,无法继续重试");
}
}
}
return rootElement;
}