## 脚本说明 - 在 Linux 运行`TShark.java`必须先安装**tshark**,在 Windows 上运行必须先安装**Wireshark**客户端,在安装时勾选**tshark**组件。 - 必须使用超级管理员账号运行`TShark.java`,这是**tshark**命令的限制,在 Windows 上可以使用管理员权限打开命令行运行。 - Java 脚本基于**Java21**开发,可直接使用`java TShark.java`运行,运行后会在当前目录下创建一个**shark.log**文件,保存抓包日志。 - 建议创建一个 bash 或者 cmd 脚本,在 bash 或 cmd 脚本中配置好 JDK 环境变量,然后再使用管理员权限运行 bash 或 cmd 脚本。 ##### TShark.java ```java import java.io.*; import java.nio.file.Path; import java.time.ZoneId; import java.util.List; import java.util.TimeZone; public final class TShark { public static void main(String[] args) throws Exception { TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("Asia/Shanghai"))); Path path = Path.of("shark.log"); File sharkLog = path.toFile(); if (!sharkLog.exists() && !sharkLog.createNewFile()) { throw new RuntimeException("create shark.log failure"); } // DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); Process process = startSharkProcess(); System.out.println("start tshark success"); startProcessSharkThread(process, sharkLog); System.out.println("start process thread success"); int exitCode = process.waitFor(); System.out.println("tshark process is dead, exit code: " + exitCode); } private static void startProcessSharkThread(Process process, File sharkLog) { Thread thread = new Thread(() -> { try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); BufferedWriter fileWriter = new BufferedWriter(new FileWriter(sharkLog, true))) { String line; while ((line = reader.readLine()) != null) { fileWriter.write(line + System.lineSeparator()); } fileWriter.flush(); } catch (Exception e) { e.printStackTrace(); } }); thread.setName("TShark-thread"); thread.start(); } public static Process startSharkProcess() throws IOException { List cmd = List.of( "tshark", "-l", "-i", "\\Device\\NPF_{807C63AC-179D-4AC8-BD56-85CE8AA179DB}", "-Y", "tcp.port == 33000 && http.request.method == \"POST\"", "-V" ); ProcessBuilder processBuilder = new ProcessBuilder(cmd); processBuilder.redirectErrorStream(true); return processBuilder.start(); } } ``` ##### 通过 NEWAPI 调用 vLLM 运行的 gpt-oss-120b 模型 ```java import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.Duration; import java.util.concurrent.CompletableFuture; public class HttpPost { public static void main(String[] args) { try (HttpClient httpClient = HttpClient.newHttpClient()) { HttpRequest httpRequest = HttpRequest.newBuilder() .uri(URI.create(apiUrl)) .header("Content-Type", "application/json") .header("Authorization", apiKey) .timeout(Duration.ofMinutes(5L)) .POST(HttpRequest.BodyPublishers.ofString(request)) .build(); CompletableFuture completableFuture = httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofLines()).thenAccept(response -> { System.out.println("SSE success status " + response.statusCode() + ", response body: "); response.body().forEach(System.out::println); }).exceptionally(throwable -> { System.out.println("SSE failure error message: " + throwable.getMessage()); throwable.printStackTrace(); return null; }); try { completableFuture.get(); } catch (Exception e) { e.printStackTrace(); } } } static final String apiUrl = "http://10.159.252.49:33000/v1/chat/completions"; static final String apiKey = "Bearer sk-rbWEGdsaZ47e2hQFZt2xRHqWRZaipYlkyLqHdU2z9FlWj7D3"; static final String request = """ { "model": "gpt-oss-120b", "messages": [ { "role": "user", "content": "成龙今年71岁,请把这句话的信息,按照`user_response`结构生成一个JSON" } ], "stream": true, "extra_body":{ "structured_outputs": true, "guided_decoding": true }, "response_format": { "type": "json_schema", "json_schema": { "name": "user_response", "schema": { "type": "object", "properties": { "name": {"type": "string"}, "age": {"type": "number"} }, "required": ["name", "age"], "additionalProperties": false }, "strict": true } } } """.strip(); } ```