ไคลเอนต์ BitTorrent ที่พัฒนาขึ้นเองตั้งแต่ศูนย์
(github.com/piyushgupta53)- Go-Torrent เป็น การใช้งานไคลเอนต์ BitTorrent ที่สร้างด้วย Go โดยพัฒนาฟังก์ชันหลักสำหรับดาวน์โหลดไฟล์ด้วยโปรโตคอล BitTorrent
- ขอบเขตการพัฒนาครอบคลุมตั้งแต่ การพาร์สไฟล์ .torrent, การค้นพบ peer, การสื่อสารกับ peer ไปจนถึงการดาวน์โหลดไฟล์ และรองรับทั้งทอร์เรนต์แบบไฟล์เดียวและหลายไฟล์
- Bencode รองรับชนิดข้อมูล string, integer, list และ dictionary พร้อมฟังก์ชันการจัดการข้อผิดพลาดและ การตรวจสอบความถูกต้อง
- ฟังก์ชันดาวน์โหลดมีการจัดการ piece และ block, การดาวน์โหลดพร้อมกัน, การติดตามความคืบหน้า และการจัดการการบันทึกในระดับ block
- โปรเจกต์ยังอยู่ระหว่าง การพัฒนาอย่างต่อเนื่อง และมีแผนรองรับ Magnet link, metadata exchange protocol และ DHT ในอนาคต
ฟีเจอร์ที่ Go-Torrent ใช้งานได้
- Go-Torrent เป็นการใช้งานไคลเอนต์ BitTorrent ที่เขียนด้วย Go
- พัฒนาฟังก์ชันหลักเพื่อให้สามารถดาวน์โหลดไฟล์ด้วยโปรโตคอล BitTorrent ได้
- ขอบเขตการใช้งานหลักมีดังนี้
- การพาร์สไฟล์ทอร์เรนต์
- การค้นพบ peer
- การดาวน์โหลดไฟล์
Bencode และการจัดการไฟล์ทอร์เรนต์
- การเข้ารหัส/ถอดรหัส Bencode รองรับชนิดข้อมูล Bencode ทั้งหมด
- string
- integer
- list
- dictionary
- รวมการจัดการข้อผิดพลาดและการตรวจสอบความถูกต้อง
- การจัดการไฟล์ทอร์เรนต์ รองรับการพาร์สไฟล์
.torrent- ทอร์เรนต์แบบไฟล์เดียว
- ทอร์เรนต์แบบหลายไฟล์
- รองรับการคำนวณ info hash และการดึง piece hash
- รองรับฟิลด์มาตรฐานของไฟล์ทอร์เรนต์
การค้นพบและการสื่อสารกับ peer
- รองรับการค้นพบ peer ผ่าน HTTP tracker
- ใช้งานโปรโตคอล handshake กับ peer
- รวมโปรโตคอลข้อความ BitTorrent แบบครบถ้วน
- มีการจัดการการเชื่อมต่อกับ peer
การดาวน์โหลดและการจัดการพื้นที่จัดเก็บ
- ฟังก์ชันดาวน์โหลดรวมการจัดการ piece และ block
- สามารถทำการดาวน์โหลดหลายรายการพร้อมกันได้
- ติดตามความคืบหน้าการดาวน์โหลด
- รองรับการประกอบไฟล์สำหรับทอร์เรนต์ทั้งแบบไฟล์เดียวและหลายไฟล์
- การจัดการพื้นที่จัดเก็บทำงานด้วย granularity ระดับ block
โครงสร้าง ข้อกำหนด และสถานะการพัฒนา
- โครงสร้างโปรเจกต์แบ่งเป็นแพ็กเกจต่อไปนี้
cmd/: อินเทอร์เฟซบรรทัดคำสั่งและแอปพลิเคชันหลักinternal/bencode/: การเข้ารหัส/ถอดรหัส Bencodeinternal/torrent/: การจัดการไฟล์ทอร์เรนต์internal/tracker/: การใช้งานโปรโตคอล trackerinternal/peer/: การสื่อสารกับ peerinternal/download/: การจัดการดาวน์โหลดpkg/: แพ็กเกจสาธารณะ
- ข้อกำหนดคือ Go 1.21 ขึ้นไป
- การติดตั้งทำโดย clone repository แล้วรัน
go mod download - เอกสารการใช้งานจะถูกเพิ่มเมื่อโปรเจกต์เติบโตสมบูรณ์ขึ้น
- สามารถตรวจสอบสถานะการใช้งานปัจจุบันได้ที่ checkpoint.md
- ฟีเจอร์ที่วางแผนไว้มีดังนี้
- รองรับ Magnet link
- Metadata exchange protocol
- รองรับ DHT(Distributed Hash Table)
- เอกสารอ้างอิงคือ BitTorrent Protocol Specification และ Bencode Specification
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ยอดเยี่ยมมาก แต่เพราะเป็นอินพุตที่เชื่อถือไม่ได้ จึงน่าจะจำกัดขนาดการจัดสรรแบบไดนามิกใน bencode decoder ไว้ด้วย
อินพุตประสงค์ร้ายจากไฟล์ torrent หรือการตอบกลับ announce อาจบังคับให้ไคลเอนต์ต้องจัดสรรหน่วยความจำขนาดใหญ่มากระหว่างการพาร์สสตริง จนทำให้ไคลเอนต์เข้าสู่ภาวะ ปฏิเสธการให้บริการ ได้ สำหรับ torrent ที่สร้างมาดี ๆ จะไม่สามารถมีสตริงที่ยาวกว่าความยาวอินพุตที่เหลืออยู่ได้ ดังนั้นถ้ากำหนดความยาวอินพุตที่เหลือเป็นเพดานก็น่าจะโอเค
ดูสะอาดและเรียบง่ายดี ชอบมาก น่าจะเพิ่ม ตัวอย่างการใช้งานหนึ่งบรรทัด ใน README สำหรับดาวน์โหลดไฟล์
.torrentจริง ๆ ด้วยเช่น:
./go-torrent My-Linux-Distro-Wink-ISO.torrentถ้าเพิ่ม
torrent.ParseFromUrlเข้าไปด้วยก็จะยิ่งดี และโปรเจกต์แบบนี้เป็นสิ่งที่ทุกคนควรลองทำสักครั้งเพื่อฝึกฝนตัวเองเจ๋งดี codecrafters มีชาเลนจ์ที่แนะนำขั้นตอนนี้อยู่บ้างและมีเทสต์ให้ด้วย ผมลองเล่นช่วงเดือนฟรีแล้วสนุกดี
https://app.codecrafters.io/courses/bittorrent/overview
เจ๋งดี ผมเองก็เคยคิดอยากทำแบบนี้เหมือนกัน อยากรู้ว่ายากแค่ไหน และถือว่า “เสร็จสมบูรณ์” ได้ในระดับไหน อยากรู้ด้วยว่ารองรับ DHT, Magnet และฟีเจอร์เจาะ NAT สารพัดอย่างหรือเปล่า
จุดที่ผมติดมาตลอดคือไม่รู้ว่าถ้าจะทำไคลเอนต์ที่ใช้งานได้กับ torrent ส่วนใหญ่ที่มีอยู่จริง ต้องมีรายการฟีเจอร์อะไรบ้าง ดูเหมือนจะมีโปรโตคอลที่เกี่ยวข้องกับ torrent เป็นสิบ ๆ ตัว และผมยังไม่รู้ด้วยซ้ำว่ารายการทั้งหมดมีอะไรบ้าง ไม่ต้องพูดถึงว่าแต่ละตัวทำอะไร
ยากจริง ๆ ต้องใช้เวลาเกือบหนึ่งเดือนกว่าจะเรียนรู้ว่าโปรโตคอลและ bencoding ทำงานอย่างไร สร้างโมเดลในหัว แล้วค่อยลงมือเขียนโค้ดจริง
Magnet และ DHT ยังไม่ได้เพิ่ม
ความยากขึ้นอยู่กับประสบการณ์ ความคุ้นเคยกับภาษาโปรแกรมที่ใช้ และท่าทีในการทดลองอย่างมาก อนึ่ง ผมเองก็เพิ่งเริ่มทำ Bittorrent client ด้วย Go เมื่อสัปดาห์ที่แล้ว และภายในหนึ่งสัปดาห์ก็ทำมาได้ประมาณ 80% ของโปรเจกต์ที่โพสต์แล้ว
แต่ผมมีประสบการณ์ Go ค่อนข้างมาก มีความรู้เรื่องโปรโตคอลและเครือข่ายพอสมควร และการทดลองก็แทบจะเป็นนิสัยที่สองไปแล้ว
ถ้าสนใจ สเปกหลักของ Bittorrent จริง ๆ แล้วค่อนข้างสั้น อ่านและทำความเข้าใจได้ง่าย ๆ ในราวหนึ่งชั่วโมง: https://www.bittorrent.org/beps/bep_0003.html
รอบ ๆ Bittorrent มีสิ่งอย่างส่วนขยายโปรโตคอลอยู่มาก แต่เท่าที่เห็นจนถึงตอนนี้ ระดับการรองรับต่างกันไปตามไคลเอนต์ ตัวอย่างเช่น Protocol Encryption แทบจะใกล้เคียงกับการทำให้เข้าใจยากมากกว่า โดยจะพยายามสื่อสารด้วยวิธีนั้นก่อน และถ้าไม่สำเร็จก็ย้อนกลับไปใช้โปรโตคอลปกติตามการตั้งค่า
ถ้าแค่ดาวน์โหลดดิสโทร Linux เช่น Debian จากไฟล์
.torrentบนเว็บไซต์ ก็ถือว่าค่อนข้างตรงไปตรงมา เป็นไฟล์เดียว มี tracker มี peer จำนวนมากที่ใช้โปรโตคอลปกติ และถ้าอยู่หลัง NAT ก็ยังพอทำได้แม้ไม่รับการเชื่อมต่อขาเข้าเมื่อขยับเข้าไปในคอนเทนต์พื้นที่สีเทาโดยธรรมชาติ ก็อาจอยากพาร์สลิงก์ Magnet, หา peer ด้วย DHT และนำ UPnP มาใช้เพื่อพยายามแมปพอร์ตบนโมเด็มโดยอัตโนมัติ ถึงอย่างนั้นสิ่งเหล่านี้ก็ยังค่อย ๆ สะสมทีละอย่างแบบวนซ้ำได้ ยิ่งมีฟีเจอร์มาก ก็ยิ่งมีโอกาสหา peer ได้มากขึ้นและแลกเปลี่ยนข้อมูลสำเร็จมากขึ้น
ไม่ใช่นักพัฒนา Go เลยอยากถามว่า ทำไมถึงใช้ Go 1.21 ที่เก่าแล้ว มีเหตุผลอะไรที่ต้องค้างอยู่กับเวอร์ชันเก่าหรือเปล่า?
แก้ไข: ดูเหมือนจะหยุดซัพพอร์ตไปเมื่อ 10 เดือนก่อน
การรองรับ Windows 7 เป็นเหตุผลหนึ่งที่อาจต้องอยู่กับ Go รุ่นเก่า โปรเจกต์ที่สร้างด้วย Go 1.21.4 หรือต่ำกว่าจะทำงานได้บน Windows ทุกรุ่นและคอมพิวเตอร์ที่ผลิตตั้งแต่ปี 2009 เป็นต้นมา แต่ถ้าอัปเป็น v1.21.5 ก็แทบไม่ได้ประโยชน์อะไร แถมจะทำงานได้เฉพาะคอมพิวเตอร์ที่ใหม่กว่าและ Windows 10/11 เท่านั้น
https://github.com/golang/go/issues/64622
README น่าจะเป็นสิ่งที่ AI สร้าง ขึ้น ไฟล์
go.modจริงระบุเวอร์ชัน Go เป็น 1.23.1[1] ซึ่งหมายความว่าต้องใช้ Go 1.23.1 ขึ้นไป[2][1] https://github.com/piyushgupta53/go-torrent-client/blob/6130...
[2] https://go.dev/doc/modules/gomod-ref#go-notes
เจ๋งมาก ทำให้นึกถึงสมัยเรียนมหาวิทยาลัย เคยทำสิ่งนี้เป็น โปรเจกต์ปลายภาค ในวิชาเครือข่ายของ Georgia Tech
โค้ดหายไปนานแล้ว แต่บทเรียนที่ได้ตอนนั้นยังอยู่ โปรเจกต์แบบนี้ยังเป็นวิธีที่ดีในการเรียนภาษาใหม่ด้วย
เป็นโปรเจกต์ประเภทที่น่าลองทำ ผมเองก็เคยทำอะไรคล้าย ๆ กัน แล้วพอได้ดู bencode encoder/decoder ที่คนอื่นทำไว้ก็รู้สึกถ่อมตัวขึ้นมาก
เป็นวิธีที่ดีในการสำรวจฟีเจอร์ของภาษาด้วย แน่นอนว่าการพยายามไล่ตามทุกฟีเจอร์ของไลบรารีขนาดใหญ่นั้นค่อนข้างไร้ประโยชน์ และผมก็คิดว่าความเข้ากันได้ระหว่างไคลเอนต์เองก็ยังไม่พออยู่แล้ว
อยากรู้ว่ามีแผนจะเผยแพร่เอกสารเกี่ยวกับขั้นตอนการ implement หรือไม่ โดยส่วนตัวแล้วสนใจส่วนนั้นมากกว่าตัวโค้ดเอง
เพราะมีแหล่งข้อมูลไม่มากนักที่เจาะลึกแนวทางหรือกระบวนการในการ implement แง่มุมต่าง ๆ ของโปรโตคอล
อยากรู้ว่าทำ v2 และ mutable torrents ด้วยหรือเปล่า ขอให้มีใครสักคน implement mutable torrents ทีเถอะ
รองรับลิงก์ Magnet ไหม?
แก้ไข: อ้อ เป็นฟีเจอร์ที่วางแผนไว้