سوکت چیست!

سوکت به دو رابط فایل مانند در دو سوی ارتباطهای شبکه ای گفته میشه که در برنامه نویسی از اونا استفاده میکنیم.

یعنی فرض کن الف و ب میخوان با هم تماس بگیرن. خب فرضا ب درحال گوش دادن برای تماس هست (سرور) و الف باهاش توسط توابع مربوطه تماس میگیره، بعد از اینکه ب ارتباط رو پذیرفت، در هر دو طرف سوکت هایی برای ارتباط ایجاد میشن که توسط توابع و روشهایی شبیه به توابع و روشهایی که با اونها در فایلهای معمولی مینویسیم و میخونیم از اونها استفاده میکنیم. یعنی مثلا وقتی در سوکتی که در سمت ب ایجاد شده اطلاعاتی رو مینویسیم، اون اطلاعات به الف ارسال میشه. و وقتی الف اطلاعاتی رو به ب ارسال میکنه اینطور بنظر میرسه که این اطلاعات در سوکت ذخیره شده که بعد با توابع خواندن از سوکت اون اطلاعات رو از سوکت استخراج میکنیم.

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

سوکت یک رابط پایه ای در ارتبط بین دو برنامهء لوکال یا ریموت هست که پروتکل خاصی نداره. یعنی شما میتونید هر دیتایی رو به هر شکلی توسط سوکت ها ارسال و دریافت کنید. این قرارداد و کار دو طرف هست که از چه پروتکل و فرمتی برای ارسال و دریافت اطلاعات استفاده کنن. بطور مثال HTTP یک پروتکل هست که روی سوکت های زیرین که از نوع TCP هستن استفاده میشه.
سوکت هایی که ما با اونها در شبکه و اینترنت سروکار و داریم عمدتا دو نوع هستن، یکی TCP و یکی UDP.

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

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

موقعی که مرورگر وب شما با سرور تماس میگیره درواقع اول یک ارتباط سوکتی TCP با اون سرور برقرار میکنه و بعد اطلاعات بر اساس فرمت و استاندارد و قراردادهای پروتکل HTTP با سرور مبادله میشن.

اتصالهای Persistent که در بحث HTTP و سرورهای وب میشنوید درواقع به اون ارتباط سوکتی TCP زیرین مربوط میشن که اگر ارتباط TCP مورد نظر فقط برای یک درخواست و پاسخ HTTP استفاده بشه و بعدش ارتباط TCP بسته بشه، یک اتصال غیر Persistent رو داریم، و اگر سوکت های TCP با یک درخواست و پاسخ از بین نرن و ارتباط TCP همچنان باز بمونه و برای درخواست و پاسخهای دیگری هم استفاده بشه، بهش اتصال Persistent گفته میشه. اتصال Persistent برای HTTP در نسخهء 1.1 پروتکل HTTP برای استفادهء بهینه تر از منابع دو طرف و سرعت بیشتر در مرورگرها و سرورها طراحی شد. اگر برای هر درخواست یک اتصال TCP مجدد ایجاد کنیم، عملیات اتصال اولیهء سوکت ها (صحبت کردن و توافق و تنظیم پارامترهای اولیه) هر بار باید تکرار بشه و این نیاز به تعداد بیشتری رفت و برگشت اطلاعات بین کلاینت و سرور داره و در نتیجه در کل زمان و منابع بیشتری در هر دو طرف مصرف میشه.

پروتکل هایی مثل HTTP, FTP و غیره همه چیزی نیستن جز قراردادهایی برای روش و فرمت و رفتارهای ارسال و دریافت اطلاعات بین دو طرف، و همهء این پروتکل ها برای ارسال واقعی اطلاعات خودشون از سوکت ها (معمولا از نوع TCP) استفاده میکنن.

———————–

میشه خیلی ساده و کلی گفت که سوکت درواقع کانال ارتباطی ما در برنامه است. یا دروازه و ابزار ارسال و دریافت اطلاعات بین ما و طرف مقابل در سطح برنامه نویسی.

و اما چیزهای مثل HTTP و FTP و SMTP و POP3 چی هستن؟
اینها پروتکل هستن. یعنی قراردادها و استانداردهایی که تعیین میکنن برنامه های مختلف چطور با هم صحبت کنن.
پروتکل مثل زبان است. مثلا زبان انگلیسی، عربی، فارسی و غیره.
و سوکت یه دستگاه ارتباطی مثل تلفن است.

شما با تلفن زنگ میزنید به طرف مقابل و اون گوشی رو برمیداره و حالا یک کانال ارتباطی بین شما وجود داره که میتونید از طریق اون صدای همدیگر رو بشنوید. این یعنی سوکت.
اما فقط توانایی تبادل صدا کافی نیست، بلکه نیاز هست طرفین به زبان مشترکی صحبت کنن تا حرف همدیگر رو متوجه بشید. این زبان مشترک همون پروتکل ها هستند.

حالا ما یه تست عملی هم انجام میدیم:

<?php

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

$result = socket_connect($socket, 'localhost', 80);

socket_write($socket, "please send me your web page!\r\n\r\n");

echo "Response:<hr>";
echo socket_read($socket, 2000);

socket_close($socket);

?>

ما در این برنامهء PHP با استفاده از سوکت به وب سرور محلی خودمون متصل میشیم، چون به پورت 80 متصل میشیم که پورت سرویس دهی HTTP است. بنابراین ما باید بعد از اتصال با سوکت، با زبان HTTP با سرور صحبت کنیم، اما ما عمدا این کار رو نکردیم و به سادگی عبارت please send me your web page رو به سرور میفرستیم که چون بر طبق قراردادهای پروتکل HTTP نیست در نتیجه سرور منظور ما رو متوجه نمیشه و در پاسخ بهمون خطای 400 Bad Request رو ارسال میکنه و در متن صفحه ای که بعنوان پیام خطای قابل مشاهده برای کاربر ارسال میکنه نوشته:

Your browser (or proxy) sent a request that
this server could not understand.

که ترجمش میشه:
مرورگر (یا پراکسی) شما درخواستی ارسال کرد که این سرور نتوانست بفهمد.

دیدید که ما با استفاده از سوکت تونستیم به یک وب سرور متصل بشیم و اطلاعاتی رو بهش ارسال کنیم و اطلاعاتی رو دریافت کنیم، تا اینجا این کار سوکت بود که بدون هیچ اشکالی هم انجام شد؛ اما چون از پروتکل لازم استفاده نکردیم، طرف مقابل منظور ما رو متوجه نشد و در نتیجه این ارتباط بی فایده بود (تنها نتیجهء مفید این بود که فهمیدیم یک برنامه روی پورت 80 فعاله که ارتباطهای TCP رو قبول میکنه).

حالا ما دوباره با سوکت به سرور متصل میشیم اما این بار با زبان پروتکل HTTP باهاش صحبت میکنیم:

<?php

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

$result = socket_connect($socket, 'localhost', 80);

socket_write($socket, "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n");

echo "Response:<hr>";
echo socket_read($socket, 2000);

socket_close($socket);

?>

در نتیجه این بار سرور منظور ما رو متوجه میشه و یک پاسخ 200 OK بهمون برمیگردونه که محتوی کدهای HTML حاصل از صفحهء index سایت ماست.

—————————–

البته توجه داشته باشید که خود سوکت هم برای برقراری ارتباط با طرف دیگر با زبان و پروتکل خاص خودش با طرف دیگر صحبت میکنه. ولی اون پروتکل و جزییات خاصش سطح پایین تر هستن و ما در برنامه نویسی باهاشون سروکار نداریم و این کارها در پشت صحنه توسط کتابخانه های مربوطه و/یا سرویسهای سیستم عامل انجام میشن.

دقیقا مثل اینکه وقتی شما شماره تلفن طرف مقابل رو میگیرید، دستگاه تلفن شما هم طوری طراحی شده تا با زبان و سیگنالهای از پیش تعیین شده ای این شماره ها رو به مرکز مخابرات انتقال بده، و این پروتکلی هست که دستگاه تلفن برای برقراری ارتباط خودش ازش استفاده میکنه.

و حتی یک سوکت TCP هم باز خودش بر پروتکل سطح پایین تری بنام IP استواره که بسته های اطلاعاتی پروتکل TCP رو در شبکه و اینترنت انتقال میده.

اما از نظر ما در برنامه نویسی سوکت، سوکت فقط دروازه یا ابزار ارسال و دریافت اطلاعات است. و ما با زبان دستورات و سینتاکس زبان برنامه نویسی و کتابخانه های مربوطهء خودمون از سوکت استفاده میکنیم.

وقتی از سوکت برای برقراری ارتباط مستقیم با برنامه های دیگر استفاده میکنیم، مجبوریم زبانهای طرف های مقابل رو هم یاد بگیریم و خودمون باهاشون به اون زبانها صحبت کنیم. مثلا اگر با یک برنامهء وب سرور تماس میگیریم، باید زبان HTTP رو که وب سرورها با اون زبان صحبت میکنن بلد باشیم و به اون زبان صحبت کنیم.

وقتی به یک برنامهء سرویس دهندهء FTP متصل میشیم، باید با زبان پروتکل FTP باهاش صحبت کنیم.

وقتی به یک سرور دریافت ایمیل POP3 متصل میشیم، باید با زبان POP3 باهاش صحبت کنیم.

و الی آخر.

اما مثلا وقتی در مرورگر با AJAX درخواستی میفرستید، مرورگر که این زبان (HTTP) رو بلده، خودش کار تماس گرفتن با سرور مربوطه و صحبت کردن به اون زبان رو انجام میده و نیازی نیست شما HTTP بلد باشید و خودتون مستقیما با سرور صحبت کنید، بلکه شما به یک زبان سطح بالاتری که زبان برنامه نویسی و API مرورگر وب شماست به مرورگر میگید که فلان فایل یا اطلاعات رو که آدرسش رو بهش میدید از فلان سرور با فلان آدرس دریافت کنه، و بعد این مرورگر هست که یک سوکت به اون سرور ایجاد میکنه و بعد با زبان پروتکل HTTP با برنامه ای که در سمت دیگر هست صحبت میکنه و مثلا میگه فلان فایل رو برام ارسال کن؛ بعد مرورگر نتیجه رو در ااختیار شما میذاره، بدون اینکه شما از اینهمه جریان در پشت صحنه مطلع بشید.

پاسخ دهید

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

*

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