آموزش برنامهنویسی شبکه
برنامهنویسی شبکه (برنامهنویسی سوکت)، روشی برای اتصال دو گره در یک شبکه برای برقراری ارتباط با یکدیگر است. در اینجا، یک سوکت (گره سرور) روی یک IP به یک پورت خاص گوش میدهد، در حالی که سوکت دیگر (گره کلاینت) سعی میکند با استفاده از IP، و پورت تعریف شده در گره سرور، به گره سرور متصل گردد. برنامهنویسی سوکت، دو سوکت را قادر میسازد تا دادهها را به صورت دو طرفه در هر لحظه ارسال و دریافت کنند. در برنامهنویسی سوکت امکان برقراری ارتباط بین دو سوکت (گره) به صورت بلادرنگ ممکن میشود و این ویژگی، امکان ساخت برنامههای کاربردی را فراهم میکند. سوکتها، ستون فقرات واقعی در پشت اینترنت اشیاء، برنامههای پیام رسان، صفحات وب، بازیهای آنلاین و ارسال دادههای بلادرنگ هستند.
انواع سوکت در برنامهنویسی شبکه
در برنامهنویسی شبکه، ۴ نوع سوکت، سوکت جریان (Stream Socket)، سوکت دیتاگرام (Datagram Socket)، سوکت خام (Raw Socket) و سوکت بستههای متوالی (Sequenced Packet Socket) در دسترس کاربران قرار دارد. اما از این چهار سوکت، سوکتهای جریان (Stream Socket) و سوکتهای دیتاگرام (Datagram Socket) بیشتر مورد استفاده قرار میگیرند.
سوکتهای جریان (Stream Sockets)
این سوکتها از پروتکل TCP برای انتقال دادهها استفاده میکنند. در هنگام استفاده از سوکت جریان، مرز بین رکوردها حفظ نمیشود.
سوکتهای دیتاگرام (Datagram Sockets)
این سوکتها از پروتکل UDP برای انتقال دادهها استفاده میکنند.
سوکتهای خام (Raw Sockets)
این سوکتها، دسترسی کاربران را به پروتکلهای ارتباطی زیربنایی (underlying communication protocols) که از انتزاع سوکت پشتیبانی میکنند، فراهم میکنند. سوکتهای خام معمولا در تجهیزات شبکه موجود هستند و برای پروتکل کنترل پیامهای اینترنتی (ICMP) و پروتکلهای مسیریابی مانند IGRP و OSPF استفاده میشوند. سوکتهای خام برای کاربران عمومی در نظر گرفته نشدهاند. سوکتهای خام عمدتا برای توسعه پروتکلهای ارتباطی جدید و دستیابی به برخی از امکانات رمزآلود یک پروتکل ارائه شدهاند.
ادامه
سوکتهای بستههای متوالی (Sequenced Packet Sockets)
سوکتهای بستههای متوالی شبیه سوکتهای جریان هستند با این تفاوت که در هنگام استفاده از سوکت بستههای متوالی مرز بین رکوردها حفظ میشود.
پروتکل TCP/IP
پروتکل TCP/IP، یک پروتکل اتصالگرا (Connection-Oriented) بوده و به عنوان یک پروتکل قابل اطمینان شناخته میشود. در این پروتکل، قبل از ارسال اطلاعات، یک ارتباط مجازی بین فرستنده و گیرنده برقرار میشود. مهمترین وظیفه پروتکل TCP/IP اطمینان از دریافت اطلاعات فرستاده شده از سوی فرستنده توسط گیرنده میباشد. با وجود امکانات زیادی که در پروتکل TCP/IP، به منظور کنترل خطاهای احتمالی در هنگام ارسال اطلاعات وجود دارد، اما این پروتکل به دلیل افزایش بار عملیاتی سیستم، کارایی پایینی دارد. در پروتکل TCP/IP، فرستنده با استفاده از پاسخ دریافتی از گیرنده (Ack)، از سلامت بسته های دریافت شده توسط گیرنده آگاهی پیدا میکند و در صورتی که دادههای ارسال شده در اختیار گیرنده قرار نگرفته باشند دادههای دریافت نشده را مجددا برای گیرنده ارسال میکند.
پروتکل UDP/IP
پروتکل UDP، یک پروتکل انتقال سریع اطلاعات بدون در نظر گرفتن مسائل امنیتی میباشد. در این پروتکل، گیرنده هیچ پاسخی (Ack) را به فرستنده ارسال نمیکند. از این رو در این پروتکل با وجود بار پردازشی کم، هیچ تضمینی در خصوص دریافت صحیح بسته وجود ندارد و ممکن است بعضی از بستههای ارسال شده توسط فرستنده، در گیرنده دریافت نشوند.
نکته
در برنامهنویسی شبکه، در صورتی که از پروتکل TCP/IP استفاده نماییم در قسمت Socket Type از مقدار socket.SOCK_STREAM، و در صورتی که از پروتکل UDP/IP استفاده نماییم از مقدار socket.SOCK_DGRAM استفاده میکنیم
پروتکل اینترنت (IP)
پروتکل اینترنت (IP)، یک آدرس عددی است که به هر یک از دستگاههای متصل به شبکه کامپیوتری اختصاص داده میشود. در حال حاضر دو نسخه از IP ارائه شده است. این دو نسخه، IPV4 و IPV6 میباشند. IPV4، یک عدد ۳۲ بیتی است که برای سادگی آن را به شکل ۴ بخش عددی در مبنای ۱۰ مینویسند. در اینجا، از آنجایی که طول هر یک از این چهار بخش یک بایت است، به هر یک از این چهار بخش یک هشتایی (Octet) گفته میشود. در اینجا هر بخش عددی میتواند مقداری بین ۰ تا ۲۵۵ را داشته باشد. در این شیوه آدرس دهی دو آدرس ۰.۰.۰.۰ و ۲۵۵.۲۵۵.۲۵۵.۲۵۵ رزرو بوده و به ترتیب به منظور مقاصد نشان دادن عدم اتصال کامپیوتر به شبکه و پخش همگانی استفاده میشوند. همچنین آدرس ۱۲۷.۰.۰.۱ که با نامهای Loopback Address و Local Host شناخته میشود برای تست پشته پروتکل TCP/IP استفاده میگردد و قابلیت برقراری ارتباط با دیگر دستگاه ها را ندارد. در زیر یک IPV4 نشان داده شده است.
۱۰۱۰۱۱۰۰.۰۰۰۱۰۰۰۰.۱۱۱۱۱۱۱۰.۰۰۰۰۰۰۰۱
۱۷۲.۱۶.۲۵۴.۱
گسترش روز افزون اینترنت و نیاز به آدرسهای بیشتر سبب گردید تا کارگروه مهندسی اینترنت (Internet Engineering Task Force)، پروتکل اینترنت نسخهی ۶ را ارائه کند تا امکان تعریف آدرسهای بیشتری ممکن گردد. پروتکل اینترنت نسخهی ۶ (IPV6)، یک عدد ۱۲۸ بیتی است که در آن از مبنای ۱۶ یا هگزادسیمال استفاده میشود. در پروتکل اینترنت نسخه ۶ امکان ادرس دهی ۲ به توان ۱۲۸ دستگاه متصل به شبکه ممکن میگردد. در IPV6، علاوه بر گسترش فضای آدرس دهی، اندازه جدول مسیریابها نیز کوچتر میشود. IPV6، شامل هشت بخش شانزده بیتی میباشد. در زیر یک IPV6 نشان داده شده است.
۲۷۰۲:A0B3:8012:D0E5:0000:0000:0000:B25F
نکته
در برنامهنویسی شبکه، در صورتی که از IPV4 استفاده نماییم در قسمت Socket Family از مقدار socket.AF.INET، و در صورتی که از IPV6 استفاده نماییم از مقدار socket.AF.INET6 استفاده میکنیم
معماری شبکه
در برنامهنویسی شبکه (برنامهنویسی سوکت)، معماری شبکه را کلاینت/سروری در نظر میگیریم. در این معماری همانطور که در شکل زیر نشان داده شده است، Connection در سمت سرور و Session در سمت کلاینت ایجاد میگردد.

پورت (Port)
هر IP دارای ۶۵۵۳۵ پورت است. پورتها شامل دو گروه رزرو شده و رزرو نشده هستند. پورتهای ۱ تا ۱۰۲۴ متعلق به گروه رزرو شده میباشند و مابقی پورتها رزرو نشده هستند. از پورتهای رزرو نشده میتوان برای اتصال به یک ماشین یا یک برنامه کاربردی استفاده نمود.
طریقه دسترسی به وضعیت پورتها در سیستم عامل ویندوز
به منظور بررسی وضعیت پورتها در سیستم عامل ویندوز دستور زیر را در Command Prompt اجرا میکنیم
netstat -aon
سپس با در نظر داشتن شناسه پروسه (PID) متناظر با هر پورت و مراجعه به تب سرویس Task Manager میتوانیم متوجه شویم که پورت مورد نظر توسط کدام برنامه استفاده میشود.
برنامه اسکن پورتهای باز به زبان پایتون
# pip install python-nmap
import nmap
my_port_scanner = nmap.PortScanner()
protocol = “tcp”
IP = “127.0.0.1”
port_range = “10-400”
my_port_scanner.scan(IP, ports=port_range)
my_open_tcp_port = my_port_scanner[IP][protocol].keys()
for port in my_open_tcp_port:
service_name = my_port_scanner[IP][protocol][port][“name”]
print(f”{port} – {service_name } : Open”)
# print (“{} – {} : Open”.format(port , service_name))
برای اینکه بتوانید برنامه اسکن پورت نوشته شده به زبان پایتون را با موفقیت بر روی سیستم عامل خود اجرا نمایید نیاز است که برنامه nmap بر روی سیستم عامل شما نصب باشد. این برنامه را میتوانید از اینجا دانلود نمایید.
دستورات برنامهنویسی شبکه مشترک در دو پروتکل TCP/IP و UDP/IP
bind |
TCP/IP | UDP/IP |
listen |
accept |
connect |
close |
دستورات برنامهنویسی شبکه در پروتکل TCP/IP
دستورات برنامهنویسی شبکه در پروتکل UDP/IP
دستور bind
از این دستور (متد) در سمت سرور و به منظور اختصاص یک IP و Port خاص به سوکت تعریف شده استفاده میشود.
دستور listen
از این دستور (متد) در سمت سرور و به منظور محدود نمودن تعداد ارتباطهای ایجاد شده با سرور استفاده میشود
دستور accept
از این دستور (متد) در سمت سرور و به منظور دریافت درخواست ارتباط کلاینت استفاده میشود. این متد اطلاعات کلاینت درخواست کننده برای برقراری ارتباط با سرور را در قالب یک تاپل شامل دو شی Connection و IP کلاینت و پورتی که کلاینت از آن برای ارتباط با سرور استفاده کرده را بر میگرداند
دستور connect
این دستور (متد) توسط کلاینت و به منظور ارتباط با سرور استفاده میشود. این متد با دریافت دو مقدار IP سرور و پورت سرور به عنوان پارامتر ورودی امکان اتصال کلاینت به سرور را ممکن میکند.
دستور recv
در صورتی که از شبکه مبتنی بر پروتکل TCP/IP استفاده نماییم، از این دستور (متد) به منظور دریافت پیام استفاده میکنیم. در هنگام استفاده از این متد، برنامه تا زمان دریافت پیام در حال انتظار میماند. این متد، مقداری را به عنوان پارامتر ورودی دریافت میکند که مشخص کننده و محدود کننده حداکثر تعداد کارکترهای پیام دریافتی بر حسب بایت میباشد. در سیستمهای کامپیوتری هر حرف یک بایت فضا اشغال میکند.
دستور send
در صورتی که از شبکه مبتنی بر پروتکل TCP/IP استفاده نماییم، از متد send برای ارسال داده استفاده مینماییم. این متد ورودی را از نوع بایت دریافت میکند. با توجه به اینکه بر روی رسانه فیزیکی دادهها به صورت دنبالهای از بیتها ارسال میشوند، بنابراین قبل از ارسال یک رشته با استفاده از متد encode رشته را به بایت تبدیل کرده و سپس آن را ارسال میکنیم. در مقصد نیز هنگام استفاده از متد recv، دادهها به صورت بایت دریافت میشوند و برای اینکه برای ما قابل فهم باشند باید آنها را به رشته تبدیل کنیم که این کار را با استفاده از متد decode انجام میدهیم.
دستور recvfrom
در صورتی که از شبکه مبتنی بر پروتکل UDP/IP استفاده نماییم از این متد به جای متد recv استفاده میکنیم.
دستور sendto