1 คะแนน โดย GN⁺ 2025-06-15 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • โปรเจ็กต์โอเพนซอร์สนี้คือ ไคลเอนต์ BitTorrent ที่พัฒนาด้วยภาษา Go โดยลงมือสร้างลอจิกพื้นฐานสำหรับการดาวน์โหลดไฟล์ขึ้นมาเอง
  • จัดการ การเข้ารหัส/ถอดรหัส Bencode ด้วยตัวเอง และมีความสามารถด้านการตรวจสอบข้อผิดพลาดที่แข็งแกร่ง
  • รองรับฟังก์ชันหลักอย่างครบถ้วน เช่น การแยกวิเคราะห์ไฟล์ .torrent, การคำนวณ info hash, การสื่อสารระหว่างเพียร์
  • มีฟีเจอร์ที่ช่วยให้ใช้งานได้จริงมากขึ้น เช่น การดาวน์โหลดพร้อมกัน การประกอบไฟล์ และการจัดการพื้นที่เก็บข้อมูลระดับบล็อก
  • เมื่อเทียบกับโอเพนซอร์ส BitTorrent ที่มีอยู่เดิม โปรเจ็กต์นี้มีจุดเด่นด้าน ความเรียบง่ายของภาษา Go, โครงสร้างโค้ดที่ชัดเจน และความเป็นโมดูล

ภาพรวม

โปรเจ็กต์นี้เป็นการสร้างไคลเอนต์ BitTorrent ขึ้นมาเองด้วยภาษา Go
ให้ความสามารถในการดาวน์โหลดไฟล์ผ่านโปรโตคอล BitTorrent ในลักษณะพัฒนาขึ้นเอง
โดยมุ่งเน้นที่ฟังก์ชันหลักอย่าง การแยกวิเคราะห์ไฟล์ทอร์เรนต์, การค้นหาเพียร์, การดาวน์โหลดไฟล์

ฟีเจอร์หลัก

  • การเข้ารหัส/ถอดรหัส Bencode

    • รองรับ Bencode ทุกประเภท เช่น สตริง จำนวนเต็ม ลิสต์ และดิกชันนารี
    • ใช้การจัดการข้อผิดพลาดและการตรวจสอบข้อมูลอย่างเข้มงวด
  • การจัดการไฟล์ทอร์เรนต์

    • แยกวิเคราะห์ได้ทั้งทอร์เรนต์ไฟล์เดี่ยวและหลายไฟล์
    • ดึง info hash และแฮชของแต่ละชิ้นส่วนได้ พร้อมรองรับทุกฟิลด์มาตรฐาน
  • การค้นหาและสื่อสารกับเพียร์

    • รองรับ HTTP tracker
    • พัฒนาโปรโตคอลแฮนด์เชกระหว่างเพียร์
    • รองรับโปรโตคอลข้อความของ BitTorrent และการจัดการการเชื่อมต่อเพียร์
  • ความสามารถด้านการดาวน์โหลด

    • จัดการในระดับชิ้นส่วนและบล็อก
    • รองรับการดาวน์โหลดพร้อมกัน
    • ติดตามความคืบหน้าการดาวน์โหลดและประกอบไฟล์
    • เพิ่มประสิทธิภาพด้วยการจัดการสตอเรจระดับบล็อก

โครงสร้างโปรเจ็กต์

  • cmd/ : อินเทอร์เฟซบรรทัดคำสั่งและไฟล์สำหรับรัน
  • internal/
    • bencode/ : ฟังก์ชันเข้ารหัสและถอดรหัส Bencode
    • torrent/ : การแยกวิเคราะห์และจัดการไฟล์ทอร์เรนต์
    • tracker/ : การพัฒนาโปรโตคอล tracker
    • peer/ : ฟังก์ชันการสื่อสารระหว่างเพียร์
    • download/ : ฟังก์ชันจัดการการดาวน์โหลด
  • pkg/ : ชุดแพ็กเกจที่สามารถเปิดเผยให้ภายนอกใช้งานได้

ข้อกำหนด

  • ต้องใช้ Go 1.21 ขึ้นไป

วิธีใช้งาน

  • ขณะนี้โปรเจ็กต์ยังอยู่ในช่วงเริ่มต้นของการพัฒนา โดยจะมีการเพิ่มคำแนะนำการใช้งานในภายหลัง

สถานะการพัฒนาและแผนงาน

  • ขณะนี้กำลังพัฒนาอย่างต่อเนื่อง
  • รายละเอียดของขั้นตอนการพัฒนาถูกบันทึกไว้ในไฟล์ checkpoint.md
  • แผนในอนาคต:
    • รองรับ Magnet link
    • โปรโตคอลแลกเปลี่ยนเมทาดาทา
    • มีแผนรองรับ DHT (Distributed Hash Table)

เอกสารอ้างอิง

  • ข้อกำหนดโปรโตคอล BitTorrent
  • ข้อกำหนด Bencode

ความสำคัญและจุดเด่นของโปรเจ็กต์

  • โปรเจ็กต์นี้ใช้ประโยชน์จาก ไวยากรณ์ที่เรียบง่ายและการทำงานแบบขนานของภาษา Go เพื่อสร้างส่วนที่ซับซ้อนของไคลเอนต์ BitTorrent ให้เป็น โมดูลที่ชัดเจน
  • โครงสร้างที่ชัดเจนและขยายต่อได้ง่าย รวมถึงดูแลรักษาได้สะดวก ทำให้มีข้อดีทั้งในแง่การเรียนรู้และการนำไปใช้จริง
  • แม้จะยังอยู่ใน ระยะเริ่มต้น แต่ก็สามารถทำฟังก์ชันหลักของโปรโตคอล BitTorrent ได้อย่างรวดเร็ว

1 ความคิดเห็น

 
GN⁺ 2025-06-15
ความคิดเห็นจาก Hacker News
  • มีข้อเสนอแนะว่าควรกำหนดเพดานขนาดของการจัดสรรหน่วยความจำแบบไดนามิกในตัวถอดรหัส bencode เพราะค่าที่รับเข้ามาจากไฟล์ทอร์เรนต์หรือจาก announce ไม่น่าเชื่อถือ และอินพุตที่เป็นอันตรายอาจขอจัดสรรหน่วยความจำขนาดใหญ่มากจนทำให้เกิดการปฏิเสธการให้บริการ (DoS) ได้ สำหรับการแยกวิเคราะห์สตริง สามารถตั้งขีดจำกัดที่เหมาะสมเป็นความยาวอินพุตที่เหลืออยู่ได้ เพราะทอร์เรนต์ที่ถูกต้องไม่ควรมีสตริงที่ยาวเกินกว่าความยาวไฟล์ที่เหลือ

    • เพิ่มประเด็นนี้เข้าไปในรายการสิ่งที่ต้องทำแล้ว
  • โปรเจ็กต์ดูสะอาดและเรียบง่ายดีมาก น่าจะดีถ้าเพิ่มตัวอย่างการใช้งานแบบบรรทัดเดียวใน Readme เช่น เพิ่มประโยคที่แสดงวิธีใช้ประมาณ ./go-torrent My-Linux-Distro-Wink-ISO.torrent และถ้าเพิ่มความสามารถ torrent.ParseFromUrl ได้ด้วยก็จะยิ่งดี ทุกคนน่าจะคุ้มค่าที่จะลองประสบการณ์แบบนี้สักครั้งใน “การเดินทางทางจิตวิญญาณ” ของตัวเอง

    • ขอบคุณสำหรับข้อเสนอแนะ
  • แนะนำชาเลนจ์ที่คล้ายกันจาก codecrafters โดยในคอร์สนี้จะมีการช่วยเรื่องความคืบหน้าของโปรเซสและการทดสอบต่าง ๆ เคยลองใช้ฟรีหนึ่งเดือนแล้วค่อนข้างสนุก
    https://app.codecrafters.io/courses/bittorrent/overview

  • ในฐานะคนที่ไม่ใช่นักพัฒนา Go สงสัยว่าทำไมถึงใช้ Go 1.21 เวอร์ชันเก่า มีเหตุผลพิเศษอะไรที่ยึดติดกับเวอร์ชันเก่าหรือไม่ พอค้นดูก็พบว่าหยุดการสนับสนุนไปแล้วตั้งแต่ 10 เดือนก่อน

    • เพราะต้องการรองรับ Windows 7 โปรเจ็กต์ที่เขียนด้วย Go 1.21.4 หรือต่ำกว่ายังทำงานได้บน Windows เกือบทุกเครื่องตั้งแต่ปี 2009 เป็นต้นมา แต่ถ้าใช้ 1.21.5 ขึ้นไป จะทำงานได้แค่บนเครื่องรุ่นใหม่และ Windows 10, 11 เท่านั้น โดยแทบไม่มีข้อดีเป็นพิเศษ
      https://github.com/golang/go/issues/64622

    • README น่าจะเขียนโดย AI เพราะในไฟล์ go.mod จริงระบุ Go เวอร์ชันเป็น 1.23.1 ดังนั้นสุดท้ายแล้วจึงต้องใช้ 1.23.1 ขึ้นไป
      https://github.com/piyushgupta53/go-torrent-client/blob/6130f4e/go.mod#L3 https://go.dev/doc/modules/gomod-ref#go-notes

  • เป็นโปรเจ็กต์ที่เจ๋งมาก ตอนเรียนมหาวิทยาลัยเคยทำสิ่งนี้เป็นโปรเจ็กต์จบในวิชาเน็ตเวิร์กของ Georgia Tech ถึงแม้โค้ดจะหายไปแล้ว แต่บทเรียนที่ได้ยังติดตัวไปตลอด โปรเจ็กต์แบบนี้เป็นวิธีที่ดีมากในการเรียนรู้ภาษาใหม่

  • มีคนถามว่ารองรับ magnet link หรือยัง
    แก้ไข: ทราบแล้วว่าเป็นฟีเจอร์ที่จะเพิ่มในอนาคต

    • ยังไม่รองรับ แต่มีแผนจะเพิ่มเร็ว ๆ นี้
  • มีคนสงสัยว่าสร้างสิ่งนี้ขึ้นมาได้อย่างไร ดูสเปกของโปรโตคอลโดยตรงหรืออ้างอิงจาก implementation อื่น ๆ หรือเปล่า เพราะสงสัยมาตลอดว่าการทำสิ่งแบบนี้จากศูนย์เริ่มต้นกันอย่างไร

    • น่าสนใจตรงที่ช่วงนี้ผมเองก็เพิ่งเริ่มสร้าง Bittorrent client ด้วย Go จากศูนย์เหมือนกัน โดยส่วนตัวไม่ค่อยชอบใช้ AI/LLM ในการเขียนโค้ด เพราะเป้าหมายคืออยากเรียนรู้ด้วยตัวเองจริง ๆ สิ่งแรกที่ทำคือไปหาสเปกอย่างเป็นทางการของโปรโตคอล Bittorrent ซึ่งจริง ๆ แล้วสเปกค่อนข้างเรียบง่าย แต่ก็มีรายละเอียดไม่มากนัก
      https://www.bittorrent.org/beps/bep_0003.html
      ส่วนส่วนขยายเพิ่มเติมอยู่ที่
      https://www.bittorrent.org/beps/bep_0000.html
      สิ่งสำคัญคือแบ่งงานออกเป็นชิ้นเล็ก ๆ มากพอที่จะตรวจสอบผลลัพธ์ได้เอง ตัวอย่างเช่นผมเริ่มจากการ parse ไฟล์ .torrent ซึ่งต้องลงมือทำ bencoding เอง พอลองดาวน์โหลด .torrent ของ Arch Linux มาก็พบว่าฟอร์แมตไม่ถูกต้อง และมีคีย์ที่ไม่คาดคิดอย่าง url-list โผล่มา พอไปค้นดูก็พบว่าเกี่ยวข้องกับ bep_0019 สุดท้ายก็ parse ไฟล์ .torrent ของ Debian Linux ได้สำเร็จ
      หลังจากนั้นก็ทำทั้งคำขอ announce แบบ HTTP ไปยัง tracker และ peer protocol ต่อ โดย peer protocol ค่อนข้างยาก และท่าทีแบบทดลองไปเรื่อย ๆ ช่วยได้มาก ผมลบ announce URL ออกจากทอร์เรนต์ Debian เพื่อให้ไม่มี peers เลย จากนั้นเพิ่มไคลเอนต์ของตัวเองเข้าไปใน KTorrent โดยตรงเพื่อสังเกตข้อความที่ส่งไปมาระหว่างกัน แล้วค่อยปรับโค้ดของตัวเองตามสิ่งที่เห็น มีการลองผิดลองถูกและดีบักอยู่มาก
      รายละเอียดบางอย่างของโปรโตคอลหาไม่เจอจริง ๆ ในเอกสารทางการ เลยมีบางครั้งที่ต้องถาม ChatGPT เล็ก ๆ น้อย ๆ และแต่ละไคลเอนต์ก็มี implementation ต่างกันเล็กน้อย ทำให้อัลกอริทึมเชิงลึกหลายอย่างไม่ชัดเจน เช่น จะเลือกบล็อกไหนมารับ จะเชื่อมต่อกับ peer ไหน และ choke/unchoke ทำงานอย่างไร สิ่งเหล่านี้ไม่มีการสรุปไว้อย่างดี การค้นหาบนเว็บช่วยได้มาก
      นอกจากนี้เว็บไซต์ https://wiki.theory.org/Main_Page ก็มีข้อมูลที่เป็นประโยชน์
      ตอนนี้ไปถึงขั้นที่ดาวน์โหลด/อัปโหลดกับ KTorrent ได้ครบแล้ว ขั้นต่อไปคือทำอัลกอริทึมสำหรับดึง peer จาก tracker เลือกบล็อกที่จะดาวน์โหลด และบันทึกลงไฟล์
      ถ้าอยากรู้กระบวนการละเอียดกว่านี้ก็ถามมาได้เสมอ
  • มีคนถามว่าการเพิ่ม GUI จะยากแค่ไหน เพราะไม่ค่อยเคยเห็นตัวอย่างการทำ GUI ด้วย Go มากนัก

    • มีหลายโปรเจ็กต์ GUI ให้เลือก https://github.com/go-graphics/go-gui-projects
      ส่วนตัวชอบ https://github.com/AllenDang/giu ซึ่งเป็น wrapper ของ ImGui
      ตัวที่ฟีเจอร์เยอะที่สุดน่าจะเป็น unison แต่ไม่แน่ใจว่าใช้งานจริงแพร่หลายแค่ไหน และน่าจะมีเอกสารค่อนข้างน้อย https://github.com/richardwilkes/unison
      Gio เป็นเฟรมเวิร์ก GUI แนวใหม่ และถูกใช้ใน Tailscale กับ gotraceui https://gioui.org
      Wails เรียนรู้ง่ายถ้ามีประสบการณ์พัฒนาเว็บ https://wails.io
      binding ของ GTK4 ก็ดูน่าสนใจ https://github.com/diamondburned/gotk4
      Cogent Core ก็ดูน่าสนุก แต่ผมลองแค่ช่วงสั้น ๆ ก่อนจะย้ายไปใช้ภาษา Odin แทน Go https://www.cogentcore.org/core
      ส่วน Fyne นั้นโดยส่วนตัวเจอปัญหาเรื่องประสิทธิภาพค่อนข้างมากในหลายเครื่องและหลายระบบปฏิบัติการ แต่ก็ยังเป็นเฟรมเวิร์ก GUI ที่ดังที่สุดอยู่ดี https://fyne.io
  • มีคนบอกว่าสนใจโปรเจ็กต์แบบนี้เลยเคยคิดว่าจะลองทำดู อยากรู้ว่ามันยากแค่ไหน และคิดว่าตอนนี้พัฒนาไปสมบูรณ์แค่ไหนแล้ว รวมถึงได้ทำฟีเจอร์ซับซ้อนอย่าง DHT, Magnet, NAT traversal หรือยัง และยังไม่แน่ใจด้วยซ้ำว่าถ้าต้องการรองรับทอร์เรนต์เกือบทั้งหมดที่มีอยู่จริง จะต้องมีรายการฟีเจอร์จำเป็นอะไรบ้าง เพราะโปรโตคอลเกี่ยวกับทอร์เรนต์มีเยอะมาก จนไม่รู้แม้แต่รายการทั้งหมดหรือแต่ละโปรโตคอลมีไว้ทำอะไร

    • ระดับความยากแตกต่างกันมากตามประสบการณ์ ความชำนาญในภาษา และทัศนคติแบบชอบทดลอง ตัวอย่างเช่นผมเองเพิ่งเริ่มทำ Bittorrent client ด้วย Go เมื่อสัปดาห์ก่อน แต่ในเวลาแค่สัปดาห์เดียวก็มาถึงประมาณ 80% ของโปรเจ็กต์ที่โพสต์ที่นี่แล้ว เพราะมีพื้นฐาน Go โปรโตคอล และเน็ตเวิร์กมากพอ และคุ้นเคยกับการลองของใหม่อยู่เสมอ
      สเปกทางการของ Bittorrent เองสั้นมาก ใช้เวลาอ่านและทำความเข้าใจประมาณชั่วโมงเดียว https://www.bittorrent.org/beps/bep_0003.html
      แต่โปรโตคอลส่วนขยายรอบข้างมีจำนวนมาก และแต่ละไคลเอนต์ก็รองรับไม่เท่ากัน ตัวอย่างเช่นหลายตัวจะลองใช้ protocol encryption ก่อน (ซึ่งจริง ๆ เป็นการทำให้อ่านยากมากกว่าการเข้ารหัส) แล้วถ้าไม่ได้ค่อยกลับไปใช้โปรโตคอลปกติ
      ถ้าคุณแค่อยากดาวน์โหลดจากไฟล์ .torrent ทางการ เช่นดิสโทร Linux ความยากจะลดลงชัดเจน เพราะมักเป็นไฟล์เดียว มี tracker และ peers ส่วนใหญ่ใช้โปรโตคอลมาตรฐาน จึงทำงานได้แม้อยู่หลัง NAT โดยไม่ต้องเปิดพอร์ตฝั่งใน
      แน่นอนว่าถ้าต้องการรองรับทอร์เรนต์ทั่วไปจริง ๆ โดยเฉพาะสายสีเทา ก็ต้องค่อย ๆ เพิ่มความสามารถอย่างการ parse magnet link, การหา peer ผ่าน DHT และ UPnP สำหรับ map พอร์ตอัตโนมัติ แต่ทั้งหมดนี้ก็ยังสามารถแบ่งทำทีละฟีเจอร์ได้ ยิ่งมีฟีเจอร์มาก ก็ยิ่งหา peer ได้มากและแลกเปลี่ยนข้อมูลได้สำเร็จมากขึ้น

    • ค่อนข้างท้าทายทีเดียว ต้องเรียนรู้ทั้งโปรโตคอล วิธีการ bencoding และวางภาพรวมของโครงสร้างทั้งหมดในหัวก่อนลงมือเขียนโค้ด ใช้เวลาเกือบหนึ่งเดือน Magnet กับ DHT ยังไม่รองรับ

  • มีคนถามว่าได้ทำ v2 และ mutable torrents หรือยัง พร้อมบอกว่าอยากให้รองรับ mutable torrents มาก ๆ