الأدلة التقنية

كيف يعمل BitTorrent؟ شرح التورنت للمبتدئين

كيف يقسم التورنت الملف إلى قطع ويتحقق منها بالهاش، وكيف يجد جهازك الأجهزة الأخرى التي تشارك الملف دون سيرفر مركزي.

كيف يعمل BitTorrent؟ شرح التورنت للمبتدئين

لنفرض أنك تريد أن توزع ملفاً حجمه 800 ميغابايت على ألف شخص، فالطريقة البسيطة هي أن تضعه على سيرفر ويب وتعطيهم الرابط، ولكن كل شخص سوف يحمل نسخة كاملة من سيرفرك، أي أن السيرفر يرفع 800 جيجابايت تقريباً، وإذا طلبوه في الساعة نفسها فسوف يبطؤ الجميع لأن عرض النطاق Bandwidth عندك محدود، وكلما زاد عدد الناس زادت المشكلة. والتورنت BitTorrent جاء ليقلب هذه المعادلة، فكل جهاز يحمل الملف يشارك في رفعه للآخرين في الوقت نفسه، وكما تقول مواصفة البروتوكول BEP 3 فميزته على HTTP العادي أن الأجهزة التي تحمل الملف نفسه في الوقت نفسه ترفع لبعضها، فيستطيع المصدر أن يخدم أعداداً كبيرة جداً مع زيادة بسيطة في حمله.

وهذا هو المقال الأول في مرحلة التورنت ومشاركة الملفات P2P، وهو مقال مفاهيم نبني عليه بقية المرحلة، وسوف نناقش في هذا المقال ما يلي:

  • لماذا يتفوق التورنت على السيرفر الواحد في توزيع الملفات الكبيرة، وما معنى Seeder وPeer وSwarm.
  • القطع Pieces والهاش، وال Info Hash الذي يعرف به كل تورنت، مع تجربة نصنع فيها ملف تورنت ونفسد بايتاً واحداً ونرى أي قطعة تفشل.
  • كيف يجد جهازك الأجهزة الأخرى: ال Tracker وال DHT وال PEX.
  • روابط Magnet، وكيف يقرر كل جهاز لمن يرفع.
  • ملف تورنت حقيقي من Debian نفحصه ونسأل ال Tracker عن عدد من يشاركونه.
  • نسبة المشاركة Seeding Ratio، والتورنت الخاص Private Torrent، وما الذي تغير في BitTorrent v2، وكلمة عن القانون.

سيرفر واحد أم سرب من الأجهزة؟

في التحميل العادي عبر HTTP كما شرحنا في HTTP وHTTPS للمبتدئين، العلاقة بين طرفين: الكلاينت Client يطلب والسيرفر Server يرسل، فإذا جاء ثلاثة أشخاص أرسل السيرفر ثلاث نسخ كاملة. أما في التورنت فالملف مقسم إلى قطع، وكل جهاز يأخذ قطعاً مختلفة، ثم يتبادل الأجهزة القطع فيما بينهم، والصورة التالية تبين الفرق:

مقارنة بين لوحين: على اليمين Plain HTTP download وفيه سيرفر ويب يرسل نسخة كاملة full copy إلى كل واحد من ثلاثة أجهزة فيرفع ثلاثة أضعاف حجم الملف، وعلى اليسار BitTorrent swarm وفيه Seeder يرسل القطع 1 إلى 3 لجهاز والقطع 4 إلى 6 لجهاز ثان والقطع 7 إلى 9 لجهاز ثالث، والأجهزة تتبادل القطع فيما بينها بأسهم زرقاء
في HTTP يتحمل السيرفر كل شيء، وفي التورنت يشارك كل جهاز في الرفع

وقبل أن نكمل، هذه المصطلحات التي سوف تتكرر في المرحلة كلها:

  • البذرة Seeder: جهاز عنده الملف كاملاً ويرفعه للآخرين، وأول Seeder هو صاحب الملف الأصلي.
  • الند Peer: أي جهاز مشارك في توزيع الملف، والكلمة تستخدم أحياناً للأجهزة التي لم تكمل التحميل بعد، وهذه تسمى أيضاً Leecher.
  • السرب Swarm: مجموعة كل الأجهزة التي تشارك الملف نفسه في هذه اللحظة، سواء كانت تحمل أو ترفع.
  • ملف التورنت Torrent File: ملف صغير بامتداد .torrent تسميه المواصفة Metainfo، فيه وصف الملف وهاش كل قطعة وعنوان ال Tracker، وليس فيه الملف نفسه.
  • ال Tracker: سيرفر يعرف من يشارك كل ملف، ويعطي كل جهاز قائمة بعناوين الأجهزة الأخرى، ولا يمر عليه أي جزء من الملف.

وقد يتساءل البعض: إذا كانت الأجهزة ترفع لبعضها، فما فائدة البذرة الأصلية بعد البداية؟ والإجابة أن السرب يحتاج أن تكون كل قطعة موجودة عند جهاز واحد على الأقل، فإذا خرجت البذرة الأصلية قبل أن تنتشر كل القطع، ولم يكن عند أي جهاز آخر نسخة كاملة، فسوف يتوقف الجميع عند نسبة معينة ولن يكملوا أبداً، لذلك تبقى البذرة الأصلية تعمل حتى تكتمل نسخ أخرى في السرب.

القطع Pieces والهاش: كيف تثق في قطعة من جهاز لا تعرفه؟

هنا السؤال الأهم في التورنت كله: أنت تحمل قطعاً من أجهزة غرباء على الإنترنت، فكيف تعرف أن القطعة التي وصلتك سليمة وأن أحداً لم يغيرها؟ والإجابة في ملف التورنت نفسه، فكما تذكر BEP 3 يقسم الملف إلى قطع متساوية الحجم ما عدا الأخيرة، ويحسب لكل قطعة هاش SHA-1 طوله 20 بايت، وتوضع كل هذه الهاشات في ملف التورنت بالترتيب. فإذا وصلتك قطعة حسبت الهاش الخاص بها وقارنته بما في الملف، فإن تطابقا حفظتها وأخبرت بقية الأجهزة أنها عندك، وإن اختلفا رميتها وطلبتها من جديد. وإذا كانت دوال الهاش جديدة عليك فقد شرحناها في التشفير للمطورين، والصورة التالية تبين الفكرة بأرقام التجربة التي سوف نقوم بها:

مخطط مرقم: الملف report-2026.bin بحجم 10 ميغابايت يقسم إلى قطع piece 0 وpiece 1 حتى piece 39 كل منها 256 كيلوبايت، ولكل قطعة هاش SHA-1 طوله 20 بايت، وكل الهاشات تحفظ في ملف .torrent بحجم 40 في 20 بايت، وتحتها حالتان: قطعة سليمة يطابق هاشها ما في الملف فتحفظ وتعلن للآخرين، وقطعة رقم 19 فيها بايت تغير عند الموقع 5000000 فلا يطابق هاشها فترمى وتحمل من جديد
كل قطعة لها هاش في ملف التورنت، والقطعة التي لا يطابق هاشها ترمى مهما كان مصدرها

التجربة: نصنع ملف تورنت ونفحصه

سوف نستخدم أدوات سطر الأوامر التي تأتي مع Transmission، وهو عميل تورنت مفتوح المصدر بترخيص GPLv2 أو GPLv3، وعلى Debian أو Ubuntu تجدها في الحزمة transmission-cli، وفيها الأداة transmission-create التي تصنع ملف التورنت، وtransmission-show التي تعرض ما بداخله. ونحن نفذنا التجربة داخل Container مبني على alpine:3.24 فيه Transmission 4.1.2 حتى لا نثبت شيئاً على الجهاز، والنتيجة نفسها على أي توزيعة. الآن نقوم بإنشاء ملف تجريبي حجمه 10 ميغابايت من بيانات عشوائية، ثم نصنع له ملف تورنت بقطع حجمها 256 كيلوبايت:

head -c 10485760 /dev/urandom > report-2026.bin
transmission-create -t http://tracker.example.internal:6969/announce -s 256 \
  -c "ArabRoot lab file" -o report-2026.torrent report-2026.bin
transmission-show report-2026.torrent

والمخرج سوف يكون كما يلي:

Creating torrent "report-2026.torrent"
1 file, 10.49 MB
40 pieces, 256 KiB each
 done!
Name: report-2026.bin
File: report-2026.torrent

GENERAL

  Name: report-2026.bin
  Hash v1: 01e0c8e9ac6a0dc03a2113665a93c5e9d1c51a66
  Created by: Transmission/4.1.2 (f234716f3e)
  Created on: Thu Oct 08 20:05:58 2026

  Comment: ArabRoot lab file
  Piece Count: 40
  Piece Size: 256 KiB
  Total Size: 10.49 MB
  Privacy: Public torrent

TRACKERS

  Tier #1
  http://tracker.example.internal:6969/announce

FILES

  report-2026.bin (10.49 MB)

في المخرج أعلاه لاحظ التالي:

  • الملف قسم إلى 40 قطعة بالضبط، لأن 10 ميغابايت (10485760 بايت) مقسومة على 256 كيلوبايت (262144 بايت) تساوي 40، وTransmission يكتب الحجم بالميغابايت العشري فيظهر 10.49 MB.
  • حجم ملف التورنت الناتج 1066 بايت فقط، منها 800 بايت هي هاشات القطع (40 قطعة في 20 بايت)، فملف التورنت وصف للملف وليس الملف نفسه.
  • السطر Hash v1 هو ال Info Hash، وهو الرقم الذي يعرف به هذا التورنت في كل مكان، وسوف نشرحه بعد قليل.
  • -s 256 تحدد حجم القطعة، وBEP 3 تذكر أن حجم القطعة يكون غالباً من قوى العدد 2، وأشهرها 256 كيلوبايت. والقطعة الكبيرة تعني ملف تورنت أصغر، ولكن القطعة الفاسدة تكلفك إعادة تحميل حجم أكبر.

نتحقق من القطع بأنفسنا ثم نفسد بايتاً واحداً

حتى لا يبقى الكلام نظرياً، كتبنا سكربت Python قصيراً يقرأ ملف التورنت بصيغته الأصلية Bencoding التي تشرحها BEP 3، ثم يحسب ال Info Hash بنفسه، ويقارن كل قطعة من الملف بالهاش المحفوظ لها:

# verify.py: read a .torrent, recompute its info hash, and check every piece of the file against it
import hashlib, sys

def bdecode(data, i=0):
    c = data[i:i+1]
    if c == b'i':                      # integer: i<number>e
        end = data.index(b'e', i)
        return int(data[i+1:end]), end + 1
    if c == b'l':                      # list: l<items>e
        i += 1; out = []
        while data[i:i+1] != b'e':
            v, i = bdecode(data, i); out.append(v)
        return out, i + 1
    if c == b'd':                      # dictionary: d<key><value>...e
        i += 1; out = {}
        while data[i:i+1] != b'e':
            k, i = bdecode(data, i)
            start = i
            v, i = bdecode(data, i)
            out[k] = v
            if k == b'info':
                out[b'__info_raw'] = data[start:i]   # the exact bytes the info hash is computed from
        return out, i + 1
    colon = data.index(b':', i)        # string: <length>:<bytes>
    n = int(data[i:colon])
    return data[colon+1:colon+1+n], colon + 1 + n

torrent, path = sys.argv[1], sys.argv[2]
meta, _ = bdecode(open(torrent, 'rb').read())
info = meta[b'info']
plen = info[b'piece length']
hashes = [info[b'pieces'][j:j+20] for j in range(0, len(info[b'pieces']), 20)]
print('info hash :', hashlib.sha1(meta[b'__info_raw']).hexdigest())
print('piece size:', plen, 'bytes,', len(hashes), 'pieces')
bad = []
with open(path, 'rb') as f:
    for n, h in enumerate(hashes):
        if hashlib.sha1(f.read(plen)).digest() != h:
            bad.append(n)
print('pieces ok :', len(hashes) - len(bad), '/', len(hashes))
print('bad pieces:', bad if bad else 'none')

الآن نشغله على الملف السليم، ثم نغير بايتاً واحداً عند الموقع 5000000 ونشغله مرة أخرى:

python3 verify.py report-2026.torrent report-2026.bin
printf "\x00" | dd of=report-2026.bin bs=1 seek=5000000 conv=notrunc 2>/dev/null
python3 verify.py report-2026.torrent report-2026.bin

والمخرج سوف يكون كما يلي:

info hash : 01e0c8e9ac6a0dc03a2113665a93c5e9d1c51a66
piece size: 262144 bytes, 40 pieces
pieces ok : 40 / 40
bad pieces: none
info hash : 01e0c8e9ac6a0dc03a2113665a93c5e9d1c51a66
piece size: 262144 bytes, 40 pieces
pieces ok : 39 / 40
bad pieces: [19]

في المخرج أعلاه لاحظ التالي:

  • ال Info Hash الذي حسبناه بأنفسنا هو نفسه الذي أظهره transmission-show، أي أنه ليس رقماً عشوائياً وإنما هاش SHA-1 لجزء معين من ملف التورنت كما سنرى.
  • تغيير بايت واحد أفسد القطعة رقم 19 وحدها، لأن الموقع 5000000 مقسوماً على 262144 يقع في القطعة 19 (الترقيم يبدأ من صفر)، وبقية القطع وعددها 39 سليمة.
  • هذا ما يفعله أي عميل تورنت مع كل قطعة تصله، فالعميل لا يحتاج أن يثق في الجهاز الذي أرسل القطعة، وإنما يثق في الهاش، والقطعة الفاسدة يعيد تحميلها فقط ولا يعيد الملف كله.

ال Info Hash: رقم الهوية لكل تورنت

ملف التورنت فيه قسم اسمه info يحتوي اسم الملف وحجمه وحجم القطعة وهاشات القطع، وفيه أيضاً أجزاء خارج هذا القسم مثل عنوان ال Tracker والتعليق وتاريخ الإنشاء. وBEP 3 تعرف ال Info Hash بأنه هاش SHA-1 طوله 20 بايت لقسم info بصيغته المرمزة كما هو في الملف، لذلك احتفظ السكربت أعلاه بالبايتات الأصلية لهذا القسم ولم يعد ترميزها. وهذا الرقم هو ما يرسله جهازك إلى ال Tracker، وما يتبادله مع كل جهاز في بداية الاتصال، فإذا لم يتطابق الرقم عند الطرفين قطع الاتصال.

ولاحظ نتيجة مهمة لهذا التعريف: تغيير التعليق أو عنوان ال Tracker لا يغير ال Info Hash لأنهما خارج قسم info، أما تغيير أي بايت في الملف أو حجم القطعة فيعطيك تورنت جديداً برقم جديد وسرباً جديداً، والسبب أن هاشات القطع جزء من قسم info.

كيف يجد جهازك الأجهزة الأخرى؟

معك الآن ملف التورنت وتعرف ما الذي تريد تحميله، ولكن من أين؟ تحتاج قائمة بعناوين IP ومنافذ لأجهزة تشارك الملف نفسه، وهناك ثلاث طرق للحصول عليها، والصورة التالية تبينها:

ثلاثة أعمدة: Tracker وفيه جهازك يرسل announce مع ال info hash إلى tracker.example:6969 ويستلم قائمة IP:port، ثم DHT وفيه جهازك يسأل عقدة node ثم عقدة أقرب إلى الهاش في أربع خطوات مرقمة حتى يصل إلى العقدة القريبة close، ثم PEX وفيه الجهاز B الذي تتصل به يخبرك أنه متصل أيضاً بالجهاز C فتتصل بالجهاز C
ال Tracker عنوان واحد يسأله الجميع، وال DHT قائمة موزعة على الأجهزة نفسها، وال PEX تبادل الأخبار بين الأجهزة المتصلة
  1. ال Tracker: عنوانه مكتوب في ملف التورنت، ويرسل له جهازك طلب Announce فيه ال Info Hash ومنفذك وكم حملت وكم بقي، فيرد بقائمة أجهزة ومدة interval بالثواني يجب أن تنتظرها قبل الطلب التالي، كما في BEP 3. وأغلب ال Trackers اليوم ترد بقائمة مضغوطة BEP 23، وكثير منها يعمل على UDP بدل HTTP حسب BEP 15. ونقطة ضعفه أنه نقطة مركزية، فإذا توقف لم يجد الأجهزة الجدد بعضهم.
  2. جدول الهاش الموزع DHT: هنا لا يوجد سيرفر مركزي، وBEP 5 تشرح أن كل عميل يعمل أيضاً عقدة Node في شبكة مبنية على خوارزمية Kademlia فوق UDP، ولكل عقدة رقم عشوائي من 160 بت، وهو نفس طول ال Info Hash. وتقاس المسافة بين رقمين بعملية XOR، فيسأل جهازك أقرب العقد التي يعرفها إلى ال Info Hash، فإما أن تعطيه أجهزة تشارك الملف، أو تعطيه عقداً أقرب، حتى يصل إلى العقد التي تحفظ قائمة هذا الملف، وبهذا يصبح كل جهاز Tracker صغيراً كما تقول المواصفة.
  3. تبادل الأجهزة PEX: بعد أن تتصل ببعض الأجهزة عبر ال Tracker أو ال DHT، يرسل لك كل جهاز قائمة بالأجهزة التي يتصل بها هو، وBEP 11 تقول إن ال PEX يعطي صورة أحدث عن السرب من المصادر الأخرى ويقلل الحاجة إلى سؤالها كثيراً، ولكنه يحتاج بداية من طريقة أخرى.

والعميل الحديث يستخدم الطرق الثلاث معاً، فإذا توقف ال Tracker استمر في إيجاد الأجهزة عبر ال DHT وال PEX، وهذا ما يجعل السرب صعب الإيقاف.

روابط Magnet: تحميل دون ملف تورنت

بما أن ال Info Hash يعرف التورنت بشكل كامل، وبما أن ال DHT يستطيع أن يجد الأجهزة من ال Info Hash وحده، فلماذا نحتاج ملف التورنت أصلاً؟ هذه هي فكرة رابط Magnet، وBEP 9 تشرح أنه رابط يحمل فقط ما يكفي للانضمام إلى السرب، أي ال Info Hash، وصيغته كما يلي:

magnet:?xt=urn:btih:<info-hash>&dn=<name>&tr=<tracker-url>&x.pe=<peer-address>

وxt فيه ال Info Hash بأربعين حرفاً ست عشرياً، وdn اسم مقترح للعرض، وtr عنوان Tracker اختياري. ونستطيع أن نطلب من transmission-show رابط Magnet لملفنا التجريبي:

transmission-show -m report-2026.torrent

والمخرج سوف يكون كما يلي:

magnet:?xt=urn:btih:01e0c8e9ac6a0dc03a2113665a93c5e9d1c51a66&dn=report-2026.bin&tr=http%3A%2F%2Ftracker.example.internal%3A6969%2Fannounce

وقد يتساءل البعض: إذا لم يكن معي ملف التورنت فمن أين أعرف هاشات القطع لأتحقق منها؟ والإجابة أن العميل يطلب قسم info نفسه من الأجهزة الأخرى في أجزاء حجمها 16 كيلوبايت عبر امتداد اسمه ut_metadata، ثم يحسب هاش SHA-1 لما وصله ويقارنه بال Info Hash الذي في الرابط، فلا يستطيع جهاز أن يرسل لك وصفاً مزوراً، والصورة التالية تبين الخطوات:

خمس خطوات مرقمة من اليمين: 1 رابط Magnet فيه urn:btih وبداية هاش Debian فقط، 2 إيجاد الأجهزة عبر DHT وtracker وPEX، 3 طلب الوصف metadata من الأجهزة نفسها في أجزاء 16 كيلوبايت عبر ut_metadata حسب BEP 9، 4 التحقق بأن SHA-1 لقسم info يساوي الهاش في الرابط، 5 تحميل القطع كالعادة، وتحتها ملاحظة أن الوصف المزور يفشل في الخطوة 4
رابط Magnet يحمل الهاش فقط، والوصف الكامل يأتي من الأجهزة ويتحقق منه بالهاش نفسه

من يرفع لمن؟ ال Choking والمعاملة بالمثل

جهازك قد يتصل بعشرات الأجهزة، ولو رفع لها كلها في الوقت نفسه لتوزعت سرعة الرفع عندك على اتصالات كثيرة بطيئة، وBEP 3 تذكر أن التحكم في الازدحام في TCP يعمل بشكل سيئ جداً مع اتصالات كثيرة في الوقت نفسه. لذلك يغلق العميل الرفع عن أغلب الأجهزة، وهذا اسمه Choking، ويفتحه Unchoking لعدد قليل منها، والخوارزمية الموصوفة في المواصفة تعمل كما يلي:

  • كل عشر ثوان يختار العميل أفضل أربعة أجهزة يحمل منها بأعلى سرعة ويريدون منه شيئاً، فيرفع لهم، وهذه هي المعاملة بالمثل Tit-for-tat: من يعطيك تعطيه.
  • جهاز واحد إضافي يختار دون النظر إلى سرعته، وهذا اسمه Optimistic Unchoke، ويتغير كل 30 ثانية، والسبب أن الجهاز الجديد لا يملك قطعاً يعطيك إياها بعد، فبدون هذه الفرصة لن يبدأ أبداً، وقد تكتشف به جهازاً أسرع من الأربعة الحاليين.
  • إذا كان الملف كاملاً عندك فأنت لا تحمل من أحد، فيختار العميل الأجهزة حسب سرعة الرفع إليها بدل سرعة التحميل منها.
جهازك في الوسط يرفع بأسهم خضراء إلى أربعة أجهزة على اليمين تحت عنوان Unchoked the 4 best تعطيك 900 و700 و650 و600 كيلوبايت في الثانية ويعاد الاختيار كل 10 ثوان، وبسهم أزرق متقطع إلى جهاز جديد أعلى اليسار تحت عنوان Optimistic unchoke يتغير كل 30 ثانية، وبقية الأجهزة أسفل اليسار تحت عنوان Choked متصلة ولكن لا يرسل لها شيء
أربعة أجهزة تعطيك أكثر، وجهاز عشوائي واحد يأخذ فرصة، والأرقام في الصورة للتوضيح

وتذكر المواصفة أيضاً أن العميل يحمل القطع بترتيب عشوائي في الغالب، حتى لا تكون كل الأجهزة تملك القطع نفسها، وفي نهاية التحميل يدخل ما يسمى Endgame Mode فيطلب القطع الأخيرة من كل الأجهزة معاً، ثم يلغي الطلبات الأخرى عند وصول القطعة، حتى لا تعلق آخر قطعة عند جهاز بطيء.

مثال حقيقي: ملف تورنت Debian

توزيعة Debian تنشر ملفات تورنت رسمية لملفات التثبيت في صفحة التحميل بالتورنت، وتقول الصفحة إن التورنت يضع حملاً قليلاً على سيرفراتهم لأن الأجهزة ترفع لبعضها، وتطلب منك أن تترك العميل يعمل بعد انتهاء التحميل لتساعد غيرك. الآن نقوم بتحميل ملف التورنت فقط، وليس ملف ال ISO، من مجلد ملفات التورنت ونفحصه:

curl -s -L -O https://cdimage.debian.org/debian-cd/current/amd64/bt-cd/debian-13.7.0-amd64-netinst.iso.torrent
wc -c debian-13.7.0-amd64-netinst.iso.torrent
transmission-show debian-13.7.0-amd64-netinst.iso.torrent

والمخرج سوف يكون كما يلي:

60948 debian-13.7.0-amd64-netinst.iso.torrent
Name: debian-13.7.0-amd64-netinst.iso
File: debian-13.7.0-amd64-netinst.iso.torrent

GENERAL

  Name: debian-13.7.0-amd64-netinst.iso
  Hash v1: 7acf8fb590b2060dd9c3146ef770169d593433b0
  Created by: mktorrent 1.1
  Created on: Sat Sep 12 11:32:11 2026

  Comment: Debian CD from cdimage.debian.org
  Piece Count: 3024
  Piece Size: 256 KiB
  Total Size: 792.7 MB
  Privacy: Public torrent

TRACKERS

  Tier #1
  http://bttracker.debian.org:6969/announce

WEBSEEDS

  https://cdimage.debian.org/cdimage/release/13.7.0/amd64/iso-cd/debian-13.7.0-amd64-netinst.iso
  https://cdimage.debian.org/cdimage/archive/13.7.0/amd64/iso-cd/debian-13.7.0-amd64-netinst.iso

FILES

  debian-13.7.0-amd64-netinst.iso (792.7 MB)

في المخرج أعلاه لاحظ التالي:

  • ملف ISO حجمه 792.7 ميغابايت وصف بملف تورنت حجمه 60948 بايت، منها 60480 بايت هاشات 3024 قطعة.
  • Debian يشغل Tracker خاصاً به على bttracker.debian.org، ومعه قسم WEBSEEDS وهو رابط HTTP عادي للملف نفسه، فإذا لم يجد عميلك أي جهاز يحمل منه، حمل القطع من سيرفر Debian مباشرة وتحقق منها بالهاش نفسه، وهذه الفكرة موصوفة في BEP 19.

والآن نسأل ال Tracker كم جهازاً يشارك هذا الملف، فال Tracker يدعم طلباً اسمه Scrape يعطي الأعداد دون قائمة الأجهزة، كما في BEP 48. وكتبنا لذلك سكربتاً قصيراً يعيد استخدام الدالة bdecode من verify.py:

# scrape.py: ask the tracker of a .torrent how many seeders and leechers it knows (BEP 48)
import hashlib, sys, urllib.parse, urllib.request
exec(open('verify.py').read().split('torrent, path')[0])          # reuse bdecode() from verify.py

meta, _ = bdecode(open(sys.argv[1], 'rb').read())
info_hash = hashlib.sha1(meta[b'__info_raw']).digest()
url = meta[b'announce'].decode().replace('/announce', '/scrape') + '?info_hash=' + urllib.parse.quote(info_hash)
reply, _ = bdecode(urllib.request.urlopen(url, timeout=20).read())
stats = reply[b'files'][info_hash]
print('tracker   :', url.split('?')[0])
print('seeders   :', stats[b'complete'])
print('leechers  :', stats[b'incomplete'])
print('completed :', stats[b'downloaded'])
python3 scrape.py debian-13.7.0-amd64-netinst.iso.torrent

والمخرج سوف يكون كما يلي، في 8 أكتوبر 2026 الساعة 20:07 بتوقيت UTC:

tracker   : http://bttracker.debian.org:6969/scrape
seeders   : 1015
leechers  : 9
completed : 672

أي أن أكثر من ألف جهاز حول العالم كانت تحمل هذا الملف كاملاً وترفعه لمن يطلبه في تلك اللحظة، وكل واحد منها يخفف الحمل عن سيرفرات Debian، والرقم يتغير من ساعة لأخرى، فإذا شغلت السكربت سوف ترى رقماً مختلفاً.

نسبة المشاركة Seeding Ratio

نسبة المشاركة Ratio هي ما رفعته مقسوماً على ما حملته، فإذا حملت ملفاً حجمه 1 جيجابايت ورفعت منه 2 جيجابايت فالنسبة 2.0، والسرب يعيش فقط إذا رفع الناس بقدر ما يحملون تقريباً، لذلك ترى صفحة Debian تطلب منك ترك العميل يعمل. وفي Transmission مثلاً يوجد إعداد seed_ratio_limit وقيمته الافتراضية 2.0 مع seed_ratio_limited وقيمته الافتراضية false كما في توثيق الإعدادات، أي أن العميل لا يتوقف عن الرفع وحده إلا إذا فعلت هذا الحد.

وعلى السيرفر انتبه لأمرين: الرفع يستهلك من باقة البيانات عند مزود ال VPS أو الإنترنت، فضع حداً للسرعة أو للنسبة يناسب باقتك، وكل جهاز في السرب يرى عنوان IP الخاص بك لأن الأجهزة تتصل ببعضها مباشرة، وهذا جزء من تصميم البروتوكول وليس خللاً فيه، وسوف نتناول الأمان والخصوصية في مقال مخطط في مرحلة التورنت. وإذا كان جهازك خلف NAT ولا يستقبل اتصالات من الخارج، فسوف تتصل أنت بالآخرين فقط، والسبب شرحناه في ما هو NAT؟.

التورنت الخاص Private Torrent

إذا وضعت في قسم info القيمة private=1، فحسب BEP 27 يجب على العميل أن يعلن نفسه فقط لل Tracker المكتوب في الملف، ويتصل فقط بالأجهزة التي يعطيه إياها، أي أنه لا يستخدم ال DHT ولا ال PEX لهذا التورنت. وبما أن العلامة داخل قسم info فهي جزء من ال Info Hash، ولا يستطيع أحد أن يحذفها دون أن يصنع تورنتاً جديداً بسرب جديد. وتنبه المواصفة إلى أن هذا ليس حماية كاملة، فالجهاز الذي يعرف عنوانك ومنفذك بأي طريقة يستطيع أن يتصل بك، وهذا هو الشكل الذي نستخدمه لتوزيع الملفات داخل المؤسسة في المقال التالي.

ما الجديد في BitTorrent v2؟

بعد أن أعلنت Google عن تصادم في SHA-1، بدأ العمل على نسخة جديدة من البروتوكول، وهي BEP 52 وحالتها في الموقع الرسمي Draft حتى الآن، ولكن مكتبة libtorrent، التي يبنى عليها عميل qBittorrent كما في ملف المشروع، دعمتها في الإصدار 2.0 في سبتمبر 2020 كما في مدونة libtorrent. وأهم ما تغير كما في الصورة التالية:

مقارنة: على اليمين v1 حسب BEP 3 بهاش SHA-1 طوله 20 بايت لكل قطعة، والملفات A وB تلصق ثم تقطع فقد تحمل قطعة نهاية A وبداية B، والهاشات قائمة واحدة مسطحة، ورابط magnet بالشكل urn:btih، وعلى اليسار v2 حسب BEP 52 بهاش SHA-256 وشجرة Merkle لكل ملف أوراقها أجزاء 16 كيلوبايت وفوقها pieces root، فكل ملف يبدأ بقطعة جديدة، والجزء الفاسد يكتشف فوراً، والملف نفسه له الهاش الرئيسي pieces root نفسه في كل تورنت، ورابط magnet بالشكل urn:btmh:1220
v1 قائمة هاشات واحدة لكل الملفات، وv2 شجرة هاش لكل ملف بأجزاء 16 كيلوبايت
  • SHA-256 بدل SHA-1: للقطع ولقسم info، وطول الهاش 32 بايت، ويقطع إلى 20 بايت عند التعامل مع ال Tracker وال DHT حتى يبقى متوافقاً معهما.
  • شجرة هاش Merkle Tree لكل ملف: أوراقها أجزاء 16 كيلوبايت، فالجزء الفاسد يكتشف فوراً ويعرف الجهاز الذي أرسله بدقة، وتقول مدونة libtorrent إن هذا يصغر قسم info الذي يحتاجه رابط Magnet، أما ملف التورنت كاملاً فلا يصغر لأنه ما زال يحفظ هاشات مستوى القطع.
  • كل ملف يبدأ بقطعة جديدة: فالملف نفسه له الهاش نفسه في أي تورنت، ويسهل اكتشاف الملفات المكررة بين أسراب مختلفة.
  • روابط Magnet جديدة: بالشكل urn:btmh: بدل urn:btih: كما في BEP 9.
  • التورنت الهجين Hybrid: ملف واحد فيه الوصفان معاً، فيشارك في سرب v1 وسرب v2 في الوقت نفسه، ويحتاج في v1 ملفات حشو Padding حسب BEP 47 حتى تبدأ الملفات عند حدود القطع.

وعلى أرض الواقع أغلب ملفات التورنت ما زالت v1، كما رأينا في ملف Debian الذي ليس فيه إلا Hash v1، لذلك ما شرحناه عن v1 في هذا المقال هو ما ستتعامل معه في الغالب.

هل التورنت قانوني؟

البروتوكول نفسه تقنية لتوزيع الملفات مثل HTTP وFTP، واستخدامه قانوني، وتستخدمه توزيعات Linux كما رأينا ومؤسسات كثيرة سوف نذكرها في المقال التالي. أما ما يخالف القانون فهو مشاركة أعمال محمية بحقوق المؤلف دون إذن أصحابها، سواء كانت أفلاماً أو برامج أو كتباً، وفي السعودية مثلاً ينظم ذلك نظام حماية حقوق المؤلف. والقاعدة بسيطة: لا تقم بتحميل أو رفع أي محتوى لا تملك حق توزيعه، والسبب أن جهازك في التورنت لا يحمل فقط وإنما يرفع أيضاً، وعنوانك ظاهر لكل من في السرب. وهذا كلام عام للتوعية وليس استشارة قانونية، فإذا كان لديك استخدام محدد في مؤسستك فارجع إلى المختص القانوني فيها.

تدريب عملي

  • اصنع ملف تورنت لمجلد فيه ثلاثة ملفات بدل ملف واحد، ثم أضف إليه Tracker ثانياً بالأمر transmission-edit -a وتأكد أن ال Info Hash لم يتغير، ثم غير المصدر بالأمر transmission-edit -s ولاحظ أن الرقم تغير، وفكر في السبب: أي القيمتين داخل قسم info؟
  • عدل verify.py حتى يطبع موقع البايت الأول والأخير لكل قطعة فاسدة، وجرب أن تغير بايتاً عند حدود قطعتين.

الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

  • التورنت يوزع الملف على سرب من الأجهزة يرفع كل منها للآخرين، فلا يتحمل المصدر الحمل وحده كما في HTTP.
  • الملف يقسم إلى قطع، ولكل قطعة هاش في ملف التورنت، والعميل يثق في الهاش وليس في الجهاز الذي أرسل القطعة، وفي التجربة أفسد بايت واحد القطعة 19 وحدها.
  • ال Info Hash هو هاش قسم info، ويعرف التورنت في ال Tracker وال DHT وروابط Magnet.
  • جهازك يجد الأجهزة الأخرى عبر ال Tracker وال DHT وال PEX، ورابط Magnet يكفيه ال Info Hash لأن الوصف يأتي من الأجهزة ويتحقق منه بالهاش.
  • العميل يرفع لأفضل أربعة أجهزة تعطيه، ولجهاز عشوائي واحد يتغير كل 30 ثانية.
  • التورنت الخاص يمنع ال DHT وال PEX ويقصر السرب على Tracker واحد، وv2 ينقل البروتوكول إلى SHA-256 وشجرة هاش لكل ملف.
  • البروتوكول قانوني، ومشاركة المحتوى المحمي دون إذن غير قانونية، وعنوانك ظاهر لكل من في السرب.

وفي المقال التالي بإذن الله نتناول الاستخدامات القانونية للتورنت، ونبني Tracker خاصاً مع ثلاثة أجهزة نقيس فيها الفرق بأنفسنا.

دليلاستخدامات التورنت القانونية وتوزيع الملفات الكبيرةأين يستخدم التورنت بشكل قانوني اليوم، وكيف توزع به ملفاً كبيراً داخل مؤسستك عبر Tracker خاص وتقيس الفرق بنفسك.دليلHTTP وHTTPS ببساطة: ماذا يحدث بين الرابط والصفحةماذا يحدث بين كتابة الرابط وظهور الصفحة، وكيف تقرأ الطلب والرد ورموز مثل 502 و504، ولماذا يكلف الاتصال الجديد أكثر.دليلالتشفير للمطورين: ماذا تستخدم ولماذا لا تخترع خوارزميتكأي هاش تستخدم لكلمات المرور، ومتى تحتاج التشفير المتماثل أو غير المتماثل، وأين تحفظ المفاتيح بأمان في تطبيقك.دليلما هو NAT؟ شرح ترجمة العناوين وتوجيه المنافذلماذا تخرج كل أجهزة بيتك بعنوان عام واحد، وكيف يترجم ال Router العناوين، ولماذا يفشل توجيه المنافذ خلف CGNAT.دليلكيف تعمل شبكة توصيل المحتوى CDN وما الذي تحفظهلماذا يبطؤ موقعك على الزائر البعيد، وكيف تقرب شبكة CDN ملفاتك منه، وكيف تمنعها من حفظ الصفحات الخاصة.

سجل التحديثات

  • أكتوبر 2026: كتابة المقال، وتنفيذ التجارب على Transmission 4.1.2 داخل Container مبني على alpine:3.24 وPython 3، وفحص ملف تورنت Debian 13.7.0 netinst وسؤال ال Tracker الخاص به في 8 أكتوبر 2026.
نشرة عرب رووت | ArabRoot

معرفة تستحق مكاناً في بريدك.

مقالات مختارة وأدوات مفيدة وأفكار لمشروعك القادم، في رسالة واحدة كل أسبوع.

يمكنك إلغاء الاشتراك متى شئت. الخصوصية

تم استلام طلبك. افتح بريدك واضغط رابط التأكيد لإتمام الاشتراك.