环境:windows10、jdk17、springboot3
需求分析,首先需要对本地某个端口进行抓包,然后用websocket将数据传到前端
1.导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>3.0.2</version>
</dependency>
2. 捕获并解析TCP包
import org.springframework.stereotype.Component;import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;@Component
public class TcpPacketCapture implements Runnable {private volatile boolean running = false;private ServerSocket serverSocket;public void start(String ip, int port) {if (!running) {running = true;bindServerSocket(ip, port);new Thread(this).start();}}public void stop() {running = false;try {if (serverSocket != null && !serverSocket.isClosed()) {serverSocket.close();}} catch (IOException e) {e.printStackTrace();}}private boolean bindServerSocket(String ip, int port) {try {serverSocket = new ServerSocket();serverSocket.bind(new InetSocketAddress(ip, port));System.out.println("Listening on " + ip + ":" + port + "...");return true; // 绑定成功} catch (IOException e) {e.printStackTrace();return false; // 绑定失败}}@Overridepublic void run() {try {while (running) {try (Socket clientSocket = serverSocket.accept();BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {String packet;while ((packet = in.readLine()) != null && running) {System.out.println("Received packet: " + packet);CustomWebSocketHandler.broadcast(packet);}} catch (IOException e) {if (running) {running = false;e.printStackTrace();}}}} finally {try {if (serverSocket != null && !serverSocket.isClosed()) {serverSocket.close();}} catch (IOException e) {e.printStackTrace();}}}
}
3.将数据用websocket传到前端
3.1 websocket配置类
import com.tcpdemo.util.CustomWebSocketHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {private final CustomWebSocketHandler customWebSocketHandler;public WebSocketConfig(CustomWebSocketHandler customWebSocketHandler) {this.customWebSocketHandler = customWebSocketHandler;}@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(customWebSocketHandler, "/ws").setAllowedOrigins("*");}
}
3.2 websocket消息处理类
package com.tcpdemo.util;import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;@Component
public class CustomWebSocketHandler extends TextWebSocketHandler {private static final CopyOnWriteArrayList<WebSocketSession> sessions = new CopyOnWriteArrayList<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {sessions.add(session);System.out.println("WebSocket connection established with session: " + session.getId());}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {sessions.remove(session);System.out.println("WebSocket connection closed with session: " + session.getId());}@Overridepublic void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {// Handle incoming messages if needed}@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {exception.printStackTrace();}public static void broadcast(String message) {for (WebSocketSession session : sessions) {if (session.isOpen()) {try {session.sendMessage(new TextMessage(message));} catch (IOException e) {e.printStackTrace();}}}}
}
3.3 前端调用接口
import com.tcpdemo.util.TcpPacketCapture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/capture")
public class CaptureController {private final TcpPacketCapture tcpPacketCapture;@Autowiredpublic CaptureController(TcpPacketCapture tcpPacketCapture) {this.tcpPacketCapture = tcpPacketCapture;}@PostMapping("/start")public String startCapture(@RequestParam String ip, @RequestParam int port) {tcpPacketCapture.start(ip, port);return "Capture started on " + ip + ":" + port;}@PostMapping("/stop")public String stopCapture() {tcpPacketCapture.stop();return "Capture stopped";}
}
4.前端接收消息
<!DOCTYPE html>
<html>
<head><title>TCP Packet Capture</title>
</head>
<body>
<h1>TCP Packet Capture</h1>
<div id="messages"></div>
<button onclick="startCapture()">Start Capture</button>
<button onclick="stopCapture()">Stop Capture</button>
<script>var ws;function startCapture() {fetch('http://localhost:8080/api/capture/start?ip=127.0.0.1&port=8081', { method: 'POST' }).then(response => response.text()).then(data => {console.log(data);ws = new WebSocket("ws://localhost:8080/ws");ws.onopen = function() {console.log("WebSocket connection established");};ws.onmessage = function(event) {var messages = document.getElementById('messages');var message = document.createElement('div');message.textContent = event.data;messages.appendChild(message);};ws.onclose = function() {console.log("WebSocket connection closed.");};ws.onerror = function(error) {console.log("WebSocket error: ", error);};});}function stopCapture() {fetch('http://localhost:8080/api/capture/stop', { method: 'POST' }).then(response => response.text()).then(data => {console.log(data);if (ws) {ws.close();}});}
</script>
</body>
</html>