پروژهء ارتباط P2P

خب با یاری خدا بالاخره کوشش های بنده به ثمر رسید و تونستم الگوریتم و ارتباط P2P همراه با ترفند Port punching رو با موفقیت پیاده سازی و آزمایش کنم. این برنامه رو که فقط یک برنامهء آزمایشی برای نشون دادن الگوریتم کلی و ارتباط P2P از طریق پروتکل UDP هست در حالتهای مختلف تست کردم. آخرین و مهمترین آزمایش، ارتباط مستقیم دو PC با هم بود که هردو پشت NAT قرار داشتن؛ بطور دقیق، دو سیستم در مکانهای مختلف که به ISP های مختلفی اتصال ADSL داشتن و مودم اونها در حالت PPPoE تنظیم شده بود. البته تست های بیشتری رو برای اطمینان و فهمیدن یکسری جزییات بیشتر ممکنه در آینده انجام بدم.

لینک دانلود برنامه

برای تست این برنامه، باید به یک هاستینگ وب هم که میشه روش از PHP استفاده کرد دسترسی داشته باشید. peer ها برای اطلاع از آنلاین بودن یکدیگر و سپس اطلاع دادن آدرس عمومی خودشون به همدیگر، نیاز به این سرور واسطه دارن، اما بعد از اون درصورت موفقیت، ارتباط به حالت P2P، یعنی مستقیم و بدون استفاده از سرور واسط وارد میشه که دو طرف میتونن بصورت نامحدود تا زمانیکه ارتباط برای مدتی گسیخته نشده به این تبادل اطلاعات مستقیم ادامه بدن؛ بخاطر همین در یک برنامهء واقعی، باید در فواصل زمانی کوتاهی، مثلا هر 10 ثانیه، هر Peer حداقل یک Packet به Peer دیگر ارسال کنه تا پورت های UDP بسته نشن. البته درصورت بسته شدن ارتباط، برنامه میتونه الگوریتم برقراری ارتباط رو از نو اجرا کنه، اما اجرای مراحل این الگوریتم، باعث تاخیر قابل توجهی میشه.

طرز راه اندازی برنامه به اینصورت هست:

- ابتدا پوشه ای بنام p2p که داخل پکیج برنامه هست و دو فایل PHP داخل اون هست باید در ریشهء یک وبسایت قرار بگیره. برنامه بوسیلهء آدرسهایی مثل http://example.com/p2p/flag.php با این دو برنامهء کوچک PHP ارتباط برقرار میکنه. البته شما میتونید اول برنامه رو بصورت لوکال تست کنید و این پوشه رو بطور مثال در دایرکتوری www برنامهء EasyPHP قرار بدید.
نکتهء خیلی مهم: فایلهای PHP باید مجوز نوشتن در دایرکتوری ای رو که در اون هستن داشته باشن. بنابراین حتما اول مجوزهای لازم رو برای پوشهء p2p تعیین کنید و از اینکه برنامه های PHP میتونن در اون پوشه فایل بنویسن و بخونن مطمئن بشید؛ در غیراینصورت برنامه نمیتونه کار خودش رو انجام بده.

- مقدار متغییر intermediary رو در فایل peer1.py و peer2.py به آدرس سایت مورد نظر تنظیم کنید. مثال:

intermediary='example.com'

- مراحل بعدی دیگه خیلی ساده هست. کافیه فایل peer1.py رو روی یکی از سیستمها اجرا کنید و فایل peer2.py رو روی سیستم دیگر. اگر کمی صبر کنید و و دو سیستم اتصال اینترنت داشته باشن و مشکلی در ارتباط با وب سرور واسط نباشه، ارتباط بعد از اجرای چند مرحلهء الگوریتم برقرار میشه. این مراحل ممکنه مجموعا چند ده ثانیه تا چند دقیقه بسته به اختلال هایی که در ارتباط پیش میان زمان ببرن، بنابراین باید بقدر کافی صبر کنید. البته با تعیین مقدار sleep_time در فایلهای peer1.py و peer2.py میتونید مقدار این زمان رو کم و زیاد کنید. بطور مثال اگر مقدار این متغییر 30 باشه، هر Peer هر 30 ثانیه با سرور واسط ارتباط برقرار میکنه تا از حضور Peer دیگر مطلع بشه. همچنین موقعی که خطایی در ارتباط با سرور واسط پیش بیاد، برنامه مجدداً بعد از این زمان برای برقراری ارتباط تلاش میکنه، و غیره. بنده مقدارش رو فعلا 10 تعیین کردم که تست ها بتونن با سرعت مناسب انجام بشن، اما در یک برنامهء واقعی بسته به شرایط و کاربرد ممکنه نیاز باشه این زمان بیشتر یا کمتر باشه.
مقدار short_sleep_time رو فکر نمیکنم نیازی باشه تغییر بدید. مقدار پیشفرضش روی 2 ثانیه هست و تنها در یکجا در مراحل انتهایی تست ارتباط بکار رفته که 5 بار تکرار میشه و بنابراین 10 ثانیه بیشتر اونم بعد از موفقیت ارتباط اولیه، زمان صرف نمیکنه.

راستی دقت کنید که همهء تنظیماتی که تغییر میدید در هر دوی peer1.py و peer2.py یکسان اعمال کنید.

در انتهای برنامهء هر peer، دو خط به اینصورت وجود داره:

input('\nPress ENTER to quit...')
break

اگر بخواید برنامه بصورت مداوم اجرا بشه، مثلا موقعی که میخواید اون رو روی یک PC کار بذارید و بعد برای تست ارتباط از طریق یک PC دیگر به جای دیگری برید که سیستم اولیه دور از دسترس خواهد بود، این دو خط رو حذف یا comment out کنید تا برنامه بصورت پیوسته به کار خودش ادامه بده و مرتبا الگوریتم رو تکرار کنه تا بتونید با خیال راحت هرچندبار که میخواید از راه دور برقراری ارتباط و کارکرد صحیح الگوریتم رو تست کنید.

یادتون نره فایلهای جانبی p2p_funcs.py و stun_client.py باید در دسترس peer1.py و peer2.py باشن.

بنده سعی کردم برنامه رو تاجایی که میتونم در حالتهای مختلف و شرایطی مثل قطع شدن ارتباط اینترنت در حین اجرای الگوریتم تست و ضعفهاش رو برطرف کنم. فکر میکنم الگوریتم نهایی نسبتا قوی و منعطف باشه، اما بهرصورت فقط یک برنامهء آزمایشی برای نشون دادن الگوریتم کلی هست که درحد محدودی تست شده و هدف کامل و دقیق بودن تمام جزییات و درنظر گرفتن تمام حالات و خطاهای ممکن و نیز بهینه سازی های جزیی نبوده. ضمنا روی استایل و پارادایم کدنویسی و اینطور چیزها هم اصلا کار نکردم و از این جهت برنامه صرفا سرهم شده و احتمالا خیلی ناخوانا هست؛ چون همونطور که گفتم فقط یک برنامهء موقت برای آزمایش و نشان دادن الگوریتم و ترفند کلی بوده.

یک نکتهء دیگه اینکه، اگر دو سیستمی که برنامه ها رو روشون تست میکنید در یک LAN باشن، برای ارتباط از آدرس محلی دو سیستم، یعنی ارتباط از طریق LAN استفاده خواهد شد (این جزیی از هوشمندی لازم برای چنین برنامه هایی هست) و دیگه ارتباط از طریق اینترنت صورت نمیگیره، چون میتونه از طریق شبکهء داخلی صورت بگیره که تقریبا همیشه سرعت و امنیت بیشتر، و هزینهء کمتری داره. بنابراین برای تست واقعی و کامل برنامه در سخت ترین و پیچیده ترین شرایط واقعی، باید ارتباط LAN بین دو سیستم رو از کار بندازید. البته الگوریتم طوری هست که اگر متوجه بشه که ارتباط دو طرفه UDP از طریق LAN امکان نداره (مثلا ممکنه توسط یک فایروال بلاک بشه) اما از طریق آدرس عمومی (معمولا اینترنت) ارتباط دو طرفه ممکن هست، سعی در برقراری ارتباط از طریق آدرس عمومی میکنه. یعنی اینقدر هوشمندی رو داره و هدف این هست که ارتباط نهایی از هر راه ممکن برقرار بشه.

شاید بپرسید که P2P باوجود اینهمه دردسر به چه دردی میخوره و چرا بجاش از یک سرور واسط استفاده نکنیم؟
باید عرض کنم شخصا متوجه مزایای بزرگ P2P شدم که باعث شد دنبال اون برم.
قبلا یک پروژهء کنترل/مانیتور از راه دور خیلی ساده و محدود نوشته بودم که بوسیلهء یک سرور واسط وب کار میکرد، اما عیب اون این بود که سرعتش پایین بود. یعنی نرم افزار مثلا هر ۳۰ ثانیه با سرور وب تماس میگرفت و فرمانهای صادر شده رو دریافت میکرد و نتایج رو برمیگردوند. همینطور طرف دیگر هم باید همین کارها رو تکرار میکرد که این باعث ناهماهنگی زمانی بین دو برنامه و نیز تاخیرهای زمانی درخواست و پاسخ سرور واسط و فاصلهء زمانی بین هر درخواست میشد چون نمیشه بطور مثال هر ثانیه یک یا چند درخواست فرستاد و دریافت کرد. یعنی این کار طبیعی و پیشبینی شده نیست و خیلی اوقات براحتی با شکست مواجه میشه، حتی با اینترنت پرسرعت. ضمنا پهنای باند وبسایت شما ممکنه در بعضی کاربردها با این روش، زیاد مصرف بشه.
برای چیزهایی مثل صدا و تصویر زنده، یا حتی یک چت سریع، هیچ چیزی بهتر از P2P کار نمیکنه بنظرم.
البته یک مزیت دیگر P2P، امنیت بیشتر اون و مقاومت بیشتر دربرابر حمله های مهمی هست. چون دیگه اطلاعات شما از یک سرور واسطه عبور نمیکنه و ضمنا به کارکرد صحیح و بهینهء این سرور در تمام طول ارتباط وابستگی ندارید.
البته مشکل امنیت اطلاعات در سرور رو میشه با رمزگذاری حل کرد، اما کار رو پیچیده تر و حجیم تر میکنه. البته کلا بکارگیری رمزنگاری در هر نرم افزاری که اطلاعات مهمی رو رد و بدل میکنه، ایدهء خوب یا لازمی هست. ضمنا کاربرد رمزنگاری فقط حفظ اطلاعات از دسترسی غیرمجاز نیست، بلکه جلوی بعضی حمله ها رو که قصد از کار انداختن برنامه یا ببار آوردن خرابی تصادفی و غیرتصادفی در رایانه های هدف رو دارن هم میگیره.

1 دیدگاه در “پروژهء ارتباط P2P

  1. سلام
    ممنونم بابات اشتارک گذاری این تجربه با ارزشتون .
    امکان داره کمی الگوریتم punching توضیح بفرمایید .
    یعنی مرحبه به مرحله چه کار باید انجام بشه .

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

*

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>