diff --git a/nex-be/src/main/java/com/unisinsight/project/controller/TestController.java b/nex-be/src/main/java/com/unisinsight/project/controller/TestController.java new file mode 100644 index 0000000..bc736d8 --- /dev/null +++ b/nex-be/src/main/java/com/unisinsight/project/controller/TestController.java @@ -0,0 +1,112 @@ +package com.unisinsight.project.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.io.*; + +@RestController("test") +@Slf4j +public class TestController { + + + private static final String BT_SCRIPT_PATH = "/var/lib/vdi/nodejs/bttorrent.sh"; + private static final String RUN_USER = "java_usr"; // 替换为你的实际用户 + + /** + * 制作种子并开始做种 + * + * @param sourceFile 源文件路径(如 /data/file.iso) + * @param torrentFile 生成的种子文件路径(如 /data/file.torrent) + * @return 是否成功 + */ + public static boolean createAndSeed(String sourceFile, String torrentFile) { + // 验证文件是否存在 + if (!new File(sourceFile).exists()) { + System.err.println("源文件不存在: " + sourceFile); + return false; + } + // 确保目标目录存在 + new File(torrentFile).getParentFile().mkdirs(); + return executeCommand("start", sourceFile, torrentFile); + } + + /** + * 停止指定文件的做种 + * + * @param sourceFile 源文件路径(如 /data/file.iso) + * @return 是否成功 + */ + public static boolean stopSeeding(String sourceFile) { + return executeCommand("stop_path", sourceFile, null); + } + + /** + * 执行 bttorrent.sh 脚本 + */ + private static boolean executeCommand(String command, String arg1, String arg2) { + try { + // 构造命令 + ProcessBuilder pb = new ProcessBuilder( + "sudo", "-u", RUN_USER, + BT_SCRIPT_PATH, + command, + arg1, + arg2 != null ? arg2 : "" // 处理可选参数 + ).redirectErrorStream(true); + // 启动进程 + Process process = pb.start(); + // 打印输出(调试用) + logProcessOutput(process); + // 等待执行完成 + return process.waitFor() == 0; + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + return false; + } + } + + /** + * 打印进程输出 + */ + private static void logProcessOutput(Process process) throws IOException { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream()))) { + String line; + while ((line = reader.readLine()) != null) { + System.out.println("[BT] " + line); + } + } + } + // 测试用例 + public static void main(String[] args) { + String sourceFile = "/var/lib/vdi/test/example.iso"; + String torrentFile = "/var/lib/vdi/test/example.torrent"; + // 测试做种 + System.out.println("开始做种..."); + boolean seedResult = createAndSeed(sourceFile, torrentFile); + System.out.println("做种结果: " + (seedResult ? "成功" : "失败")); + // 测试停止 + System.out.println("停止做种..."); + boolean stopResult = stopSeeding(sourceFile); + System.out.println("停止结果: " + (stopResult ? "成功" : "失败")); + } + + @GetMapping("/start") + public String start(@RequestParam("sourceFile")String sourceFile, + @RequestParam("torrentFile")String torrentFile) { + System.out.println("开始做种..."); + boolean seedResult = createAndSeed(sourceFile, torrentFile); + System.out.println("做种结果: " + (seedResult ? "成功" : "失败")); + return "success"; + } + + @GetMapping("/stop") + public String stop(@RequestParam("sourceFile")String sourceFile) { + // 测试停止 + System.out.println("停止做种..."); + boolean stopResult = stopSeeding(sourceFile); + System.out.println("停止结果: " + (stopResult ? "成功" : "失败")); + return "success"; + } +} diff --git a/nex-be/src/main/java/com/unisinsight/project/tb/JavaSeeder.java b/nex-be/src/main/java/com/unisinsight/project/tb/JavaSeeder.java deleted file mode 100644 index 71fca45..0000000 --- a/nex-be/src/main/java/com/unisinsight/project/tb/JavaSeeder.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.unisinsight.project.tb; - -import com.turn.ttorrent.client.Client; -import com.turn.ttorrent.client.SharedTorrent; - -import java.io.File; -import java.net.InetAddress; - -public class JavaSeeder { - public static void main(String[] args) throws Exception { - // 1. 种子文件和原始文件 - File torrentFile = new File("4.txt.torrent"); // 输出的种子文件 - File file = new File("D:\\temp\\log\\3.txt"); // 要共享的文件 -// - String trackerUrl = "udp://tracker.openbittorrent.com:80/announce"; // Tracker URL - TorrentCreator111.createTorrent(file, trackerUrl, torrentFile); - System.out.println("Torrent file created successfully: " + torrentFile.getAbsolutePath()); - - // 1. 加载种子和文件 - SharedTorrent torrent = SharedTorrent.fromFile( - torrentFile, - file.getParentFile() - ); - - // 2. 创建客户端并启用 DHT - Client client = new Client( - InetAddress.getLocalHost(), // 绑定本机 IP - torrent - ); - - // 3. 开始做种 - client.share(); - System.out.println("DHT 做种已启动..."); - - } -} \ No newline at end of file diff --git a/nex-be/src/main/java/com/unisinsight/project/tb/TorrentCreator111.java b/nex-be/src/main/java/com/unisinsight/project/tb/TorrentCreator111.java deleted file mode 100644 index 6e8056c..0000000 --- a/nex-be/src/main/java/com/unisinsight/project/tb/TorrentCreator111.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.unisinsight.project.tb; - -import java.io.*; -import java.nio.file.Files; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class TorrentCreator111 { - private static final int PIECE_LENGTH = 256 * 1024; // 256KB 分块大小 - - public static void createTorrent(File file, String announceUrl, File outputTorrent) - throws IOException, NoSuchAlgorithmException { - // 计算文件哈希 - List pieceHashes = calculatePieceHashes(file); - - // 构建info字典 - Map info = new HashMap<>(); - info.put("name", file.getName()); - info.put("piece length", PIECE_LENGTH); - info.put("pieces", concatenateHashes(pieceHashes)); - info.put("length", file.length()); - - // 构建整个torrent字典 - Map torrent = new HashMap<>(); - torrent.put("announce", announceUrl); - torrent.put("info", info); - - // 编码并写入文件 - byte[] torrentData = Bencode.encode(torrent); - try (FileOutputStream fos = new FileOutputStream(outputTorrent)) { - fos.write(torrentData); - } - } - - private static List calculatePieceHashes(File file) - throws IOException, NoSuchAlgorithmException { - List pieceHashes = new ArrayList<>(); - MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); - - try (InputStream is = Files.newInputStream(file.toPath())) { - byte[] buffer = new byte[PIECE_LENGTH]; - int bytesRead; - - while ((bytesRead = is.read(buffer)) != -1) { - sha1.reset(); - sha1.update(buffer, 0, bytesRead); - pieceHashes.add(sha1.digest()); - } - } - - return pieceHashes; - } - - private static byte[] concatenateHashes(List pieceHashes) { - byte[] result = new byte[pieceHashes.size() * 20]; // SHA-1哈希是20字节 - int offset = 0; - - for (byte[] hash : pieceHashes) { - System.arraycopy(hash, 0, result, offset, hash.length); - offset += hash.length; - } - - return result; - } - - // Bencode编码工具类 - private static class Bencode { - public static byte[] encode(Object obj) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - encode(obj, baos); - return baos.toByteArray(); - } - - private static void encode(Object obj, OutputStream out) throws IOException { - if (obj instanceof String) { - encodeString((String) obj, out); - } else if (obj instanceof Integer || obj instanceof Long) { - encodeInteger(((Number) obj).longValue(), out); - } else if (obj instanceof Map) { - encodeDictionary((Map) obj, out); - } else if (obj instanceof List) { - encodeList((List) obj, out); - } else if (obj instanceof byte[]) { - encodeBytes((byte[]) obj, out); - } else { - throw new IllegalArgumentException("Unsupported type: " + obj.getClass()); - } - } - - private static void encodeString(String s, OutputStream out) throws IOException { - out.write((s.length() + ":").getBytes()); - out.write(s.getBytes()); - } - - private static void encodeInteger(long i, OutputStream out) throws IOException { - out.write(("i" + i + "e").getBytes()); - } - - private static void encodeDictionary(Map dict, OutputStream out) throws IOException { - out.write('d'); - for (Map.Entry entry : dict.entrySet()) { - encode(entry.getKey().toString(), out); - encode(entry.getValue(), out); - } - out.write('e'); - } - - private static void encodeList(List list, OutputStream out) throws IOException { - out.write('l'); - for (Object item : list) { - encode(item, out); - } - out.write('e'); - } - - private static void encodeBytes(byte[] bytes, OutputStream out) throws IOException { - out.write((bytes.length + ":").getBytes()); - out.write(bytes); - } - } - - public static void main(String[] args) { - try { - File fileToShare = new File("D:\\temp\\log\\2.txt"); // 要共享的文件 - String trackerUrl = "http://tracker.openbittorrent.com:80/announce"; // Tracker URL - File torrentFile = new File("2.txt.torrent"); // 输出的种子文件 - - createTorrent(fileToShare, trackerUrl, torrentFile); - System.out.println("Torrent file created successfully: " + torrentFile.getAbsolutePath()); - } catch (Exception e) { - e.printStackTrace(); - } - } -} \ No newline at end of file