diff --git a/src/main/java/com/pt/utils/BdecodeUtils.java b/src/main/java/com/pt/utils/BdecodeUtils.java
deleted file mode 100644
index c77f8b4..0000000
--- a/src/main/java/com/pt/utils/BdecodeUtils.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.pt.utils;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.*;
-
-public class BdecodeUtils {
-    public static Object decode(byte[] data) throws IOException {
-        try (ByteArrayInputStream in = new ByteArrayInputStream(data)) {
-            return decodeNext(in);
-        }
-    }
-
-    private static Object decodeNext(InputStream in) throws IOException {
-        int prefix = in.read();
-        if (prefix == -1) {
-            throw new IOException("Unexpected end of stream");
-        }
-
-        if (prefix >= '0' && prefix <= '9') {
-            // 字符串，回退一个字节给parseString处理
-            in.reset();
-            return parseString(in, prefix);
-        } else if (prefix == 'i') {
-            return parseInteger(in);
-        } else if (prefix == 'l') {
-            return parseList(in);
-        } else if (prefix == 'd') {
-            return parseDict(in);
-        } else {
-            throw new IOException("Invalid bencode prefix: " + (char) prefix);
-        }
-    }
-
-    private static String parseString(InputStream in, int firstDigit) throws IOException {
-        // 读长度前缀
-        StringBuilder lenStr = new StringBuilder();
-        lenStr.append((char) firstDigit);
-        int b;
-        while ((b = in.read()) != -1 && b != ':') {
-            lenStr.append((char) b);
-        }
-        int length = Integer.parseInt(lenStr.toString());
-
-        // 读内容
-        byte[] buf = new byte[length];
-        int read = in.read(buf);
-        if (read < length) throw new IOException("Unexpected end of stream reading string");
-        return new String(buf);
-    }
-
-    private static long parseInteger(InputStream in) throws IOException {
-        StringBuilder intStr = new StringBuilder();
-        int b;
-        while ((b = in.read()) != -1 && b != 'e') {
-            intStr.append((char) b);
-        }
-        return Long.parseLong(intStr.toString());
-    }
-
-    private static List<Object> parseList(InputStream in) throws IOException {
-        List<Object> list = new ArrayList<>();
-        int b;
-        while ((b = in.read()) != 'e') {
-            in.reset();
-            list.add(decodeNext(in));
-        }
-        return list;
-    }
-
-    private static Map<String, Object> parseDict(InputStream in) throws IOException {
-        Map<String, Object> map = new LinkedHashMap<>();
-        int b;
-        while ((b = in.read()) != 'e') {
-            in.reset();
-            String key = (String) decodeNext(in);
-            Object value = decodeNext(in);
-            map.put(key, value);
-        }
-        return map;
-    }
-}
-
diff --git a/src/main/java/com/pt/utils/BencodeCodec.java b/src/main/java/com/pt/utils/BencodeCodec.java
new file mode 100644
index 0000000..2117d43
--- /dev/null
+++ b/src/main/java/com/pt/utils/BencodeCodec.java
@@ -0,0 +1,216 @@
+package com.pt.utils;
+
+import java.io.*;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+public class BencodeCodec {
+
+    /* ------------- 编码部分 ------------- */
+
+    public static void encode(Object obj, OutputStream out) throws IOException {
+        if (obj instanceof String) {
+            encodeString((String) obj, out);
+        } else if (obj instanceof Number) {
+            encodeInteger(((Number) obj).longValue(), out);
+        } else if (obj instanceof byte[]) {
+            encodeBytes((byte[]) obj, out);
+        } else if (obj instanceof List) {
+            encodeList((List<?>) obj, out);
+        } else if (obj instanceof Map) {
+            encodeMap((Map<String, Object>) obj, out);
+        } else {
+            throw new IllegalArgumentException("Unsupported type: " + obj.getClass());
+        }
+    }
+
+    public static byte[] encode(Object obj) {
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+            encode(obj, baos);
+            return baos.toByteArray();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void encodeString(String s, OutputStream out) throws IOException {
+        byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
+        out.write(String.valueOf(bytes.length).getBytes(StandardCharsets.US_ASCII));
+        out.write(':');
+        out.write(bytes);
+    }
+
+    private static void encodeBytes(byte[] bytes, OutputStream out) throws IOException {
+        out.write(String.valueOf(bytes.length).getBytes(StandardCharsets.US_ASCII));
+        out.write(':');
+        out.write(bytes);
+    }
+
+    private static void encodeInteger(long value, OutputStream out) throws IOException {
+        out.write('i');
+        out.write(Long.toString(value).getBytes(StandardCharsets.US_ASCII));
+        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 encodeMap(Map<String, Object> map, OutputStream out) throws IOException {
+        out.write('d');
+        List<String> keys = new ArrayList<>(map.keySet());
+        Collections.sort(keys);  // bencode字典必须按key排序
+        for (String key : keys) {
+            encodeString(key, out);
+            encode(map.get(key), out);
+        }
+        out.write('e');
+    }
+
+    /* ------------- 解码部分 ------------- */
+
+    public static Object decode(byte[] data) throws IOException {
+        try (ByteArrayInputStream in = new ByteArrayInputStream(data)) {
+            in.mark(data.length);
+            return decodeNext(in);
+        }
+    }
+
+    private static Object decodeNext(InputStream in) throws IOException {
+        int prefix = in.read();
+        if (prefix == -1) {
+            throw new IOException("Unexpected end of stream");
+        }
+
+        in.mark(1024);
+
+        if (prefix >= '0' && prefix <= '9') {
+            in.reset();
+            return parseString(in);
+        } else if (prefix == 'i') {
+            return parseInteger(in);
+        } else if (prefix == 'l') {
+            return parseList(in);
+        } else if (prefix == 'd') {
+            return parseDict(in);
+        } else {
+            throw new IOException("Invalid bencode prefix: " + (char) prefix);
+        }
+    }
+
+    private static String parseString(InputStream in) throws IOException {
+        StringBuilder lenStr = new StringBuilder();
+        int b;
+        while ((b = in.read()) != -1 && b != ':') {
+            if (b < '0' || b > '9') {
+                throw new IOException("Invalid string length character: " + (char) b);
+            }
+            lenStr.append((char) b);
+        }
+        if (b == -1) {
+            throw new IOException("Unexpected end of stream reading string length");
+        }
+        int length = Integer.parseInt(lenStr.toString());
+
+        byte[] buf = new byte[length];
+        int offset = 0;
+        while (offset < length) {
+            int read = in.read(buf, offset, length - offset);
+            if (read == -1) {
+                throw new IOException("Unexpected end of stream reading string data");
+            }
+            offset += read;
+        }
+
+        return new String(buf, StandardCharsets.UTF_8);
+    }
+
+    private static long parseInteger(InputStream in) throws IOException {
+        StringBuilder intStr = new StringBuilder();
+        int b;
+        while ((b = in.read()) != -1 && b != 'e') {
+            intStr.append((char) b);
+        }
+        if (b == -1) {
+            throw new IOException("Unexpected end of stream reading integer");
+        }
+        return Long.parseLong(intStr.toString());
+    }
+
+    private static List<Object> parseList(InputStream in) throws IOException {
+        List<Object> list = new ArrayList<>();
+        int b;
+        while (true) {
+            in.mark(1);
+            b = in.read();
+            if (b == -1) {
+                throw new IOException("Unexpected end of stream reading list");
+            }
+            if (b == 'e') {
+                break;
+            }
+            in.reset();
+            list.add(decodeNext(in));
+        }
+        return list;
+    }
+
+    private static Map<String, Object> parseDict(InputStream in) throws IOException {
+        Map<String, Object> map = new LinkedHashMap<>();
+        int b;
+        while (true) {
+            in.mark(1);
+            b = in.read();
+            if (b == -1) {
+                throw new IOException("Unexpected end of stream reading dictionary");
+            }
+            if (b == 'e') {
+                break;
+            }
+            in.reset();
+            String key = (String) decodeNext(in);
+            Object value = decodeNext(in);
+            map.put(key, value);
+        }
+        return map;
+    }
+
+    /* ------------- 其他辅助方法 ------------- */
+
+    // 构造单个compact peer的二进制格式 (4字节IP + 2字节端口)
+    public static byte[] buildCompactPeer(String ip, int port) {
+        try {
+            InetAddress addr = InetAddress.getByName(ip);
+            ByteBuffer buffer = ByteBuffer.allocate(6);
+            buffer.put(addr.getAddress());
+            buffer.putShort((short) port);
+            return buffer.array();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // 构造多个compact peer的二进制拼接
+    public static byte[] buildCompactPeers(List<String> ips, List<Integer> ports) {
+        if (ips.size() != ports.size()) throw new IllegalArgumentException("IPs and ports list size mismatch");
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        for (int i = 0; i < ips.size(); i++) {
+            out.write(buildCompactPeer(ips.get(i), ports.get(i)), 0, 6);
+        }
+        return out.toByteArray();
+    }
+
+    // 构造tracker响应字典，至少包含interval和peers
+    public static byte[] buildTrackerResponse(int interval, byte[] peersCompact) {
+        Map<String, Object> dict = new LinkedHashMap<>();
+        dict.put("interval", interval);
+        dict.put("peers", peersCompact);
+        return encode(dict);
+    }
+}
diff --git a/src/main/java/com/pt/utils/BencodeUtils.java b/src/main/java/com/pt/utils/BencodeUtils.java
deleted file mode 100644
index 2d3850d..0000000
--- a/src/main/java/com/pt/utils/BencodeUtils.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.pt.utils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-
-public class BencodeUtils {
-
-    // 通用bencode编码接口
-    public static void encode(Object obj, OutputStream out) throws IOException {
-        if (obj instanceof String) {
-            encodeString((String) obj, out);
-        } else if (obj instanceof Number) {
-            encodeInteger(((Number) obj).longValue(), out);
-        } else if (obj instanceof byte[]) {
-            encodeBytes((byte[]) obj, out);
-        } else if (obj instanceof List) {
-            encodeList((List<?>) obj, out);
-        } else if (obj instanceof Map) {
-            encodeMap((Map<String, Object>) obj, out);
-        } else {
-            throw new IllegalArgumentException("Unsupported type: " + obj.getClass());
-        }
-    }
-
-    public static byte[] encode(Object obj) {
-        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
-            encode(obj, baos);
-            return baos.toByteArray();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static void encodeString(String s, OutputStream out) throws IOException {
-        byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
-        out.write(String.valueOf(bytes.length).getBytes(StandardCharsets.US_ASCII));
-        out.write(':');
-        out.write(bytes);
-    }
-
-    private static void encodeBytes(byte[] bytes, OutputStream out) throws IOException {
-        out.write(String.valueOf(bytes.length).getBytes(StandardCharsets.US_ASCII));
-        out.write(':');
-        out.write(bytes);
-    }
-
-    private static void encodeInteger(long value, OutputStream out) throws IOException {
-        out.write('i');
-        out.write(Long.toString(value).getBytes(StandardCharsets.US_ASCII));
-        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 encodeMap(Map<String, Object> map, OutputStream out) throws IOException {
-        out.write('d');
-        List<String> keys = new ArrayList<>(map.keySet());
-        Collections.sort(keys);  // bencode字典必须按key排序
-        for (String key : keys) {
-            encodeString(key, out);
-            encode(map.get(key), out);
-        }
-        out.write('e');
-    }
-
-    // 构造单个compact peer的二进制格式 (4字节IP + 2字节端口)
-    public static byte[] buildCompactPeer(String ip, int port) {
-        try {
-            InetAddress addr = InetAddress.getByName(ip);
-            ByteBuffer buffer = ByteBuffer.allocate(6);
-            buffer.put(addr.getAddress());
-            buffer.putShort((short) port);
-            return buffer.array();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    // 构造多个compact peer的二进制拼接
-    public static byte[] buildCompactPeers(List<String> ips, List<Integer> ports) {
-        if (ips.size() != ports.size()) throw new IllegalArgumentException("IPs and ports list size mismatch");
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        for (int i = 0; i < ips.size(); i++) {
-            out.write(buildCompactPeer(ips.get(i), ports.get(i)), 0, 6);
-        }
-        return out.toByteArray();
-    }
-
-    // 构造tracker响应字典，至少包含interval和peers
-    public static byte[] buildTrackerResponse(int interval, byte[] peersCompact) {
-        Map<String, Object> dict = new LinkedHashMap<>();
-        dict.put("interval", interval);
-        dict.put("peers", peersCompact);
-        return encode(dict);
-    }
-}
