1 điểm bởi GN⁺ 2025-06-15 | 1 bình luận | Chia sẻ qua WhatsApp
  • Dự án mã nguồn mở này là một trình khách BitTorrent được triển khai bằng ngôn ngữ Go, tự hiện thực logic tải tệp cơ bản
  • Tự xử lý mã hóa/giải mã Bencode, đồng thời bao gồm khả năng kiểm tra lỗi mạnh mẽ
  • Hỗ trợ toàn diện các tính năng cốt lõi như phân tích tệp .torrent, tính toán info hash, giao tiếp giữa các peer
  • Bao gồm các tính năng tăng tính thực tiễn như tải xuống đồng thời, ghép tệp, quản lý lưu trữ theo khối
  • So với các mã nguồn mở BitTorrent hiện có, dự án có thế mạnh về sự đơn giản của Go, cấu trúc mã rõ ràng và tính mô-đun

Tổng quan

Dự án này tự triển khai một trình khách BitTorrent bằng Go
Nó cung cấp khả năng tải tệp sử dụng giao thức BitTorrent theo hình thức tự phát triển
Trọng tâm là các chức năng phân tích tệp torrent, khám phá peer và tải tệp

Tính năng chính

  • Mã hóa/giải mã Bencode

    • Hỗ trợ mọi kiểu Bencode như chuỗi, số nguyên, danh sách và từ điển
    • Áp dụng xử lý lỗi mạnh mẽ và kiểm tra dữ liệu
  • Xử lý tệp torrent

    • Có thể phân tích cả torrent một tệp và nhiều tệp
    • Trích xuất info hash và hash của từng piece, hỗ trợ mọi trường chuẩn
  • Khám phá và giao tiếp với peer

    • Hỗ trợ HTTP tracker
    • Triển khai giao thức bắt tay giữa các peer
    • Thực hiện giao thức thông điệp BitTorrent và quản lý kết nối peer
  • Chức năng tải xuống

    • Quản lý theo piece và block
    • Xử lý tải xuống đồng thời
    • Theo dõi tiến độ tải xuống và ghép tệp
    • Cung cấp hiệu quả nhờ quản lý lưu trữ theo block

Cấu trúc dự án

  • cmd/ : giao diện dòng lệnh và tệp thực thi
  • internal/
    • bencode/ : chức năng mã hóa và giải mã Bencode
    • torrent/ : phân tích và xử lý tệp torrent
    • tracker/ : triển khai giao thức tracker
    • peer/ : chức năng giao tiếp giữa các peer
    • download/ : chức năng quản lý tải xuống
  • pkg/ : tập hợp các package có thể cung cấp ra bên ngoài

Yêu cầu

  • Cần Go 1.21 trở lên

Cách sử dụng

  • Hiện dự án vẫn đang ở giai đoạn phát triển ban đầu, hướng dẫn sử dụng sẽ được bổ sung sau

Tình trạng phát triển và kế hoạch

  • Hiện đang được phát triển tích cực
  • Các giai đoạn phát triển chi tiết được ghi trong tệp checkpoint.md
  • Kế hoạch sắp tới:
    • Hỗ trợ liên kết Magnet
    • Giao thức trao đổi metadata
    • Dự kiến hỗ trợ DHT (bảng băm phân tán)

Tài liệu tham khảo

  • Đặc tả giao thức BitTorrent
  • Đặc tả Bencode

Ý nghĩa và điểm mạnh của dự án

  • Dự án tận dụng cú pháp đơn giản và khả năng song song đặc trưng của Go để triển khai các thành phần phức tạp của một trình khách BitTorrent theo cách mô-đun hóa rõ ràng
  • Cấu trúc rõ ràng, dễ mở rộng và dễ bảo trì mang lại lợi ích cho cả việc học tập lẫn ứng dụng thực tế
  • Dù vẫn ở giai đoạn tương đối sớm, dự án đã nhanh chóng hiện thực các chức năng cốt lõi của giao thức BitTorrent

1 bình luận

 
GN⁺ 2025-06-15
Ý kiến trên Hacker News
  • Có đề xuất nên giới hạn kích thước cấp phát bộ nhớ động trong bộ giải mã bencode. Vì dữ liệu đầu vào từ file torrent hoặc từ announce không đáng tin cậy, đầu vào độc hại có thể yêu cầu cấp phát rất lớn và gây từ chối dịch vụ (DoS). Với việc phân tích chuỗi, có thể đặt giới hạn trên hợp lý là độ dài phần đầu vào còn lại, vì một torrent hợp lệ không thể chứa chuỗi dài hơn phần còn lại của file

    • Đã thêm góp ý này vào danh sách việc cần làm
  • Dự án trông gọn gàng và đơn giản nên rất thích. Có vẻ sẽ tốt hơn nếu thêm ví dụ sử dụng một dòng vào Readme. Ví dụ, nên thêm một câu minh họa cách dùng như ./go-torrent My-Linux-Distro-Wink-ISO.torrent. Nếu còn thêm cả tính năng torrent.ParseFromUrl thì càng được điểm hơn. Ai cũng nên thử trải nghiệm kiểu này một lần cho “hành trình tinh thần” của riêng mình

    • Cảm ơn về đề xuất
  • Giới thiệu một thử thách tương tự do codecrafters cung cấp. Khóa này hỗ trợ theo dõi tiến trình và kiểm thử, và tôi đã thử miễn phí một tháng, khá thú vị
    https://app.codecrafters.io/courses/bittorrent/overview

  • Không phải là lập trình viên Go nên tôi thắc mắc tại sao lại dùng phiên bản cũ Go 1.21. Có lý do đặc biệt nào để cố dùng bản cũ không? Tìm ra thì thấy đã hết hỗ trợ từ 10 tháng trước

  • Đây thực sự là một dự án rất tuyệt. Hồi đại học tôi từng làm cái này như bài tập cuối kỳ trong lớp mạng ở Georgia Tech; code thì đã mất rồi nhưng những bài học rút ra thì theo tôi cả đời. Những dự án như thế này là cách rất tốt để học một ngôn ngữ mới

  • Có người hỏi liệu nó có hỗ trợ magnet link không.
    Edit: Giờ thì đã biết đó là tính năng sẽ được thêm trong tương lai

    • Chưa hỗ trợ, nhưng sẽ sớm thêm vào
  • Tôi tò mò không biết bạn đã làm thứ này như thế nào. Bạn có tự đọc đặc tả giao thức không, hay tham khảo các triển khai khác? Tôi luôn thắc mắc người ta bắt đầu triển khai từ con số 0 kiểu này ra sao

    • Trùng hợp là gần đây tôi cũng bắt đầu tự viết một Bittorrent client bằng Go. Cá nhân tôi không thích dùng AI/LLM để code, vì mục tiêu là thực sự tự học. Việc đầu tiên tôi làm là tìm đặc tả chính thức của giao thức Bittorrent. Thực ra đặc tả đơn giản hơn tôi nghĩ, nhưng cũng khá sơ sài
      https://www.bittorrent.org/beps/bep_0003.html
      Các phần mở rộng bổ sung ở
      https://www.bittorrent.org/beps/bep_0000.html
      Điều quan trọng là chia công việc thành những phần thật nhỏ và tự kiểm chứng kết quả từng bước. Ví dụ, tôi bắt đầu từ việc phân tích file .torrent, và phải tự triển khai bencoding. Khi tải file .torrent của Arch Linux về thì lại thấy định dạng không hợp lệ, xuất hiện các khóa ngoài dự kiến như url-list. Tìm hiểu thêm thì hóa ra liên quan đến bep_0019. Cuối cùng tôi đã phân tích thành công file .torrent của Debian Linux
      Sau đó tôi tiếp tục triển khai yêu cầu HTTP announce với tracker và cả giao thức peer. Giao thức peer khá khó, và cách tiếp cận thích thử nghiệm giúp ích rất nhiều. Tôi xóa announce URL khỏi torrent Debian để nó hoàn toàn không có peers, rồi thêm trực tiếp client của mình vào KTorrent để quan sát các thông điệp gửi qua lại, sau đó chỉnh code của mình theo những gì quan sát được. Có rất nhiều lần thử-sai và gỡ lỗi
      Một số chi tiết giao thức nhỏ thì tôi hoàn toàn không tìm thấy trong tài liệu chính thức, nên đôi lúc cũng có hỏi ChatGPT chút ít; ngoài ra mỗi client lại triển khai hơi khác nhau nên các thuật toán chi tiết không thật sự rõ ràng. Ví dụ như chọn block nào để nhận, kết nối với peer nào, choke/unchoke hoạt động ra sao... đều không được tổng kết tử tế. Tìm kiếm trên web giúp ích rất nhiều
      Ngoài ra trang https://wiki.theory.org/Main_Page cũng có khá nhiều thông tin hữu ích
      Hiện giờ nó đã ở mức có thể tải xuống/tải lên hoàn chỉnh với KTorrent. Bước tiếp theo là lấy peer từ tracker, xây dựng thuật toán chọn block để tải và ghi chúng vào file
      Nếu muốn hỏi sâu hơn về quá trình chi tiết thì cứ hỏi tiếp
  • Có người hỏi việc thêm GUI sẽ khó đến mức nào. Tôi hiếm khi thấy ví dụ làm GUI bằng Go

  • Tôi từng nghĩ có thể thử làm một dự án như thế này vì cũng quan tâm. Tôi muốn biết nó khó đến đâu và bạn đánh giá mức độ hoàn thiện hiện tại thế nào, liệu đã triển khai các tính năng phức tạp như DHT, Magnet, NAT traversal chưa. Thực ra tôi cũng không rõ để bao phủ được gần như mọi torrent ngoài đời thì chính xác cần những tính năng nào. Có quá nhiều giao thức liên quan đến torrent nên tôi còn không biết đầy đủ danh sách, chứ chưa nói đến việc hiểu từng giao thức làm gì

    • Mức độ khó thay đổi rất nhiều tùy kinh nghiệm, mức độ thành thạo ngôn ngữ và thói quen thử nghiệm. Ví dụ như tôi cũng mới bắt đầu viết Bittorrent client bằng Go từ tuần trước, vậy mà chỉ sau một tuần đã làm được khoảng 80% so với dự án được đăng ở đây. Tôi tiến triển nhanh vì có nhiều kiến thức về Go, giao thức, mạng và quen với việc thử nghiệm
      Bản thân đặc tả chính thức của Bittorrent thật ra rất ngắn, có thể đọc và hiểu trong khoảng một giờ https://www.bittorrent.org/beps/bep_0003.html
      Nhưng các giao thức mở rộng xung quanh thì rất nhiều, và mức độ hỗ trợ lại khác nhau giữa các client. Ví dụ, nhiều nơi sẽ thử mã hóa giao thức trước (thực tế là làm rối) rồi nếu không được mới quay về giao thức thường
      Nếu bạn chỉ muốn tải các file chính thức như bản phân phối Linux từ file .torrent chính thức thì độ khó chắc chắn thấp hơn. Thường chỉ là một file, có tracker, và phần lớn peer dùng giao thức chuẩn, nên ngay cả trong môi trường NAT cũng vẫn hoạt động đủ tốt mà không cần mở cổng nội bộ
      Tất nhiên, nếu muốn hỗ trợ torrent phổ thông hơn (đặc biệt là ở vùng xám) thì sẽ dần phải thêm phân tích magnet link, DHT để tìm peer, và UPnP để tự động ánh xạ cổng. Nhưng ngay cả như vậy, bạn vẫn có thể chia nhỏ và triển khai từng tính năng một theo từng bước. Càng nhiều tính năng thì càng tìm được nhiều peer hơn và trao đổi thành công hơn

    • Nó khá thử thách; tôi mất gần một tháng để học giao thức và cách bencoding hoạt động, hình dung toàn bộ cấu trúc trong đầu rồi mới viết code. Hiện vẫn chưa hỗ trợ Magnet và DHT

  • Có người hỏi liệu đã triển khai v2 và mutable torrents chưa. Đồng thời bày tỏ mong muốn nhất định hãy hỗ trợ mutable torrents