آشنایی با سوکت های شبکه در سی و لینوکس - بخش سوم

در بخش های پیشین درباره سوکت های اینترنت (Internet Socket) و ساختارهای درون هسته لینوکس برای نمایش یک سوکت گفتیم. در دنباله آموزش، در این نوشته می خواهیم با تابع ()socket و مفاهیمی همچون آدرس فامیلی (Address Family) و گونه های سوکت گفتگو کنیم.

تابع ()socket

در هر دو سوی کلاینت و سرور، نخستین گام برای ساخت یک سوکت، فراخوانی و مقداردهی درست تابع ()socket است. بر پایه کد زیر، این تابع سه ورودی را دریافت می کنند که به ترتیب آدرس فامیلی، نوع سوکت و پروتکل را نشان می دهند. مقدار برگشتی این تابع نیز بر پایه آنچه که در بخش یکم گفتیم، یک شماره صحیح است که در واقع یک توصیفگر فایل (File Descriptor) به یک فایل سوکت باز شده است.

int socket(int domain, int type, int protocol);
https://virgool.io/linux-internals/%D8%A2%D8%B4%D9%86%D8%A7%DB%8C%DB%8C-%D8%A8%D8%A7-%D8%B3%D9%88%DA%A9%D8%AA-%D9%87%D8%A7%DB%8C-%D8%B4%D8%A8%DA%A9%D9%87-%D8%AF%D8%B1-%D8%B3%DB%8C-%D9%88-%D9%84%DB%8C%D9%86%D9%88%DA%A9%D8%B3-%D8%A8%D8%AE%D8%B4-%DB%8C%DA%A9%D9%85-wbohvfgswvmm
https://virgool.io/linux-internals/آشنایی-با-سوکت-های-شبکه-در-سی-و-لینوکس-بخش-دوم-e4ku3bqi7tsj

پارامتر domain آدرس فامیلی را مشخص می کند که می تواند یکی از چندین مورد باشد که سه مقدار AF_INET و AF_INET6 یا AF_RAW برخی از آنها هستند. چون می خواهیم سوکت هایی روی شبکه (اینترنت سوکت) را بسازیم، پس اگر نشانی IP به کار رفته IPv4 باشد، پس ورودی نخست AF_INET وگرنه برای IPv6 برابر با AF_INET6 است.

آدرس فامیلی گونه یا فرمت آدرس ورودی را برای سوکت نشان می دهد. برای نمونه نشانی 192.168.1.100 یک IPv4 خصوصی (محلی) برای رایانه شما است و نشانی - 0:0:0:0:0ffff:c0a8:164 نسخه IPv6 آن است. بنابراین برای ارتباط ها بر پایه IPv4 باید از AF_INET و بر پایه IPv6 از AF_INET6 کمک بگیریم.

پارامتر type گونه ارتباط میان دو سو را نشان می دهد که چون داریم درباره سوکت های اینترنت می گویم، پس ارتباط می تواند TCP یا UDP باشد. اگر می خواهیم ارتباط از نوع TCP باشد، پس باید مقدار SOCK_STREAM وگرنه برای UDP باید مقدار SOCK_DGRAM را به کار ببریم.

پروتکل TCP یک پروتکل امن، پایدار و دو سویِ (دو طرفه - Two Way)، بر پایه اتصال (Connection Based) است در حالی که UDP بر پایه دیتاگرام (DGRAM = DataGRAM)، ناپایدار و بی اتصال (Connection Less) است.

فهرستی فراگیر از همه گزینه ها برای آدرس فامیلی و نوع ارتباط را می توانید از اینجا بخوانید یا در لینوکس خود دستور man 2 socket را اجرا کنید.

سومین ورودی که protocol نام دارد، برای ساخت سوکت های اینترنت TCP و UDP همیشه دارای مقدار صفر است. توجه کنید هر سه ورودی ()socket از گونه int هستند و در واقع AF_INET و AF_INET6 و SOCK_STREAM و SOCK_DGRAM و دیگر گزینه ها، همگی به یک شماره صحیح اشاره دارند. همگی این گزینه ها در فایل سرآیند sys/socket.h به ریخت ماکروهای سی (دستورهای define) همانند شکل زیر شناسانده شده اند.

Socket Macros
Socket Macros

بر پایه شکل بالا می توانید ببینید که AF_INET برابر با ۱ و AF_INET6 برابر با ۱۰ است و SOCK_STREAM و SOCK_DGRAM برابر با ۱ و ۲ هستند. کدهای زیر به ترتیب سوکت های TCP و UDP را ساخته اند و از این رو متغیر های tcp_socket و udp_socket به ترتیب دو توصیفگر فایل هستند که از این پس برای اشاره به سومت ها به کار رفته و به دیگر تابع های فرستاده می شوند.

tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
udp_socket = socket(AF_INET, SOCK_DGRAM, 0);