و اما رسیدیم به احتمالاً مهمترین و معروفترین پروتکل شبکه یعنی TCP. در بخش معرفی UDP گفتیم که UDP یک ارتباط بدون اتصال (ConnectionLess) هست؛ بدین معنی که دو طرف یک ارتباط، قبل از ارسال داده، گفتگو یا مذاکرهای با هم ندارند. TCP در مقابل این وضعیت قرار می گیره و به عبارتی اتصال گرا (Connection Oriented) است. تعریف اتصال گرایی TCP اینه که قبل از ارسال داده و برای شروع این ارتباط؛ دو طرف مذاکره ی کوچک اما مهمی انجام میدن و در حین تبادل داده نیز، وضعیت ارتباط به طور مرتب چک خواهد شد.
یک ارتباط همواره با درخواست از طرف کلاینت آغاز میشه. توجه داشته باشید که اصطلاحات کلاینت و سرور در تعریف استاندارد TCP نیامده (در UDP هم نیامده)؛ و هر دو طرف بدون توجه به کلاینت یا سرور بودن، توان ارسال و دریافت داده رو دارند. اما برای تفهیم بهتر، در متون مرتبط، از مفهوم کلاینت/سرور استفاده شده؛ ما نیز از این کلمات استفاده خواهیم کرد.
قبل از اینکه هر یک از دو طرف، بتوانند دادهای ارسال کنند؛ در یک پروسه ی 4 مرحلهای، یک ارتباط، ایجاد و پایدار (Stable) میشود. ابتدا کلاینت؛ درخواست برقراری ارتباط را به همراه تنظیماتی که دراینارتباط نیازمند آن است؛ به سرور میفرستد. در مرحله دوم، سرور این درخواست را تأیید (Acknowledge) میکند. در گام سوم مجدداً سرور، تنظیمات موردنیاز خود را به اطلاع کلاینت میرساند و در مرحله آخر (چهارم) پیغام مرحله 3 توسط کلاینت تأیید (Ack) میشود. در این نقطه، اصطلاحاً ارتباط پایدار (Stable) شده است. از این نقطه به بعد، هر دو دستگاه میتوانند به طرف مقابل، دادهای ارسال کنند. هر سگمنتی از داده که ارسال میشود؛ دارای شماره شناسایی است و طرف مقابل بایستی دریافت سگمنت را با ارسال پیام ACK با فرمت تعریف شده؛ اطلاع دهد. چنانچه دادهها به ترتیبی غیر از ترتیب ارسال به گیرنده برسد (به دلیل وجود روترها در میانه راه)؛ گیرنده با استفاده از شمارههای شناسایی؛ میتواند دادهها رو به نحو صحیح در محل خود گذاشته و استفاده کند (بهعنوانمثال هنگام ارسال یک فایل بزرگ).
در انتهای کار و برای بستن این ارتباط نیز، پروسهای 4 مرحله ای انجام می شود. سمتی که دیگر داده ای برای ارسال ندارد(کلاینت یا سرور)؛ پیغام درخواست اتمام ارتباط را می فرستد و منتظر دریافت ACK از طرف مقابل می شود. در این زمان، این سمت اصطلاحا در وضعیت close wait قرار میگیرد. این انتظار به این دلیل است که سمت دیگر، شاید هنوز داده ای برای ارسال داشته باشد. سمت دیگر نیز بعد از اینکه تمام داده های خود را ارسال کرد؛ پیغام اتمام خود را بایستی ارسال کرده و منتظر دریافت ACK از سمت مقابل بماند. به این حالت هم اصطلاحا Fin wait گویند.
ازآنجاییکه در آغاز ارتباط؛ مراحل 2 و 3 از سمت سرور، معمولا در یک پیغام انجام می گیرد؛ چهار مرحله در 3 پیغام خلاصه می شود. به این مراحل، اصطلاحا “دست دهی سه مرحله ای” (3 phase Handshake) یا “فاز دست دهی سه گانه” گفته می شود. نام دیگر آن، مرحله یا فاز SYN است. اتمام یک ارتباط، اما؛ بطور معمول در همان 4 مرحله انجام می پذیرد.

برقراری ارتباط TCP

اتمام یک ارتباط TCP
در حالت عادی و قبل از شروع یک ارتباط؛ اصطلاحاً سرور در حالت شنود (Listen) بر روی پورت موردنظر قرار دارد. به این وضعیت Passive Open نیز گفته میشود. برای شروع یک ارتباط، کلاینت اولین سگمنت با نام SYN را ارسال میکند. به این عمل، اصطلاحاً Active Open گفته میشود.
احتمالاً مهمترین اطلاعاتی که هر دو سمت در یک ارتباط استفاده خواهند کرد؛ شماره ترتیب (Sequence Number) و شماره تأیید (Acknoledge Number) است. اجازه بدید با یک مثال موضوع رو روشن کنیم. فرض کنید در یک ارتباط بین دو هاست که ما آنها را A و B نامگذاری کردیم، هاست A قصد ارسال یک فایل 5000 بایتی را دارد. چون حجم فایل بزرگ است؛ فرستنده تصمیم میگیرد این فایل را به قسمت های 1000 بایتی تقسیم و ارسال کند. در ابتدا سیستم A “شماره ترتیب“ خودش رو 1 اعلام میکنه و 1000 بایت اول رو به سیستم B ارسال میکنه. شماره ترتیب در این مرحله به این معنی است که بایت هایی که در این سگمنت هست؛ از بایت شماره 1 شروع میشوند، بالطبع چون 1000 بایت ارسال شده؛ بایت آخر، بایت هزارم هست. سیستم B بعد از دریافت این سگمنت، یک جواب تایید به A ارسال میکند که درون آن اصطلاحا “شماره تایید“ خودش رو، 1001 اعلام میکنه، به این معنی که B به A اعلام میکنه؛ داده های تا قبل از بایت 1001 به درستی توسط B دریافت شده اند و B منتظر دریافت بایت هزار و یکم به بعد است. در گام بعدی؛ 1000 بایت دوم با seq num=1001 ارسال می شود؛ یعنی شروع داده ها در این سگمنت از بایت هزار و یکم هست. گیرنده با دریافت این سگمنت به فرستنده پیغامی میفرستد با Ack Num=2001 یعنی بایت ها تا بایت 2000 به درستی دریافت و منتظر دریافت بایت های 2001 به ببعد هست و الی آخر…
توجه داشته باشید؛ ازآنجاییکه هر دو سمت قادر به ارسال داده هستند؛ لذا هر دو طرف، همزمان دارای Seq Num و Ack Num متعلق به خود هستند. Seq Num برای دادههای ارسالی و Ack Num برای دادههای دریافتی، مورداستفاده قرار میگیرند.
احتمالاً اگر سؤالاتی دارید مثل “اگر سگمنتی گم بشه؛ چی؟” یا “اگر سگمنتها با ترتیبی غیر از ترتیب ارسال؛ به گیرنده برسند؛ چی؟” باید بگیم در پروتکل TCP تمهیداتی برای این موارد هم دیده شده که ما سعی میکنیم بعضی از اونها رو اینجا توضیح بدیم ولی برای اطلاع بیشتر میتونید به سند RFC 793 و بهروزرسانیهای اون مراجعه کنید.
نکته بسیار مهم هم اینکه؛ به دلیل رعایت موارد امنیتی و پیشبینیپذیر نبودن شماره ترتیبها (Seq Num) و جلوگیری از بعضی حملات هکری، Seq Num از صفر شروع نمیشود و جهت این کار از یک عدد تصادفی استفاده میشود. پس Seq Num درای آفست هست.
طبق معمول، بریم سروقت هدر TCP :

هدر tcp
Source & Dstination Ports: در این دو بخش که هر کدام دو بایت نیاز دارند؛ شماره پورت مبدأ و مقصد اعلام میگردد.
Seq Num & Ack Num: همونطور که گفتیم؛ در این بخشهای چهاربایتی، شماره ترتیب و تأیید هر طرف اعلام میشه. در شروع یک ارتباط (هندشیک سهمرحلهای) مقدار اولیه (مقدار تصادفی که نشاندهنده آفست هست) در Seq Num قرار می گیره و بیت SYN که در بخش Flags قرار دارد؛ یک میشود. بهعنوانمثال، کلاینت در آغاز هندشیک با SYN=1 مقدار SEQ NUM=12345 رو اعلام میکنه؛ یعنی اینکه عدد صفر از سمت کلاینت 12345 هست؛ پس در مراحل انتقال داده، اولین Seq Num برابر با 12346 خواهد بود. این مقدار آفست از طرف سرور و در هنگام ارسال Ack Num لحاظ میشود. سرور نیز در پاسخ (هنگام فاز دوم از هندشیک)، همین کار را انجام میدهد؛ یعنی یک عدد تصادفی بهعنوان مقدار آفست شماره ترتیب خودش اعلام میکنه و بیت SYN رو یک میکنه. علاوه بر این سرور در پیغام خودش بیت ACK که در بخش Flags قرار داره رو هم ست میکنه که دریافت پیام مرحله اول رو اطلاع بده.
Header Length: یا طول هدر؛ یک بخش 4 بیتی هست و چون اندازه هدر برحسب کلمات چهاربایتی (DWORD) محاسبه شده، عدد داخل آن باید در 4 ضرب بشه تا اندازه هدر بر حسب بایت بدست بیاید. حداقل مقدار در این بیتها “0101” معادل 5 خواهد بود که یعنی هدر 5*4=20 بایت هست. ماکزیمم عدد هم 15 هست که یعنی هدر حداکثر 60 بایت خواهد بود. توجه داشته باشید که بخش اصلی هدر 20 بایتی هست اما یک بخش با نام Options در هدر قرار دارد که طول آن بین 0 (بدون Option) تا 40 بایت (حداکثر Option) تغییر میکند.
Flags: ا 12 بیت باقیمانده در کنار Heade Length عموماً بنام پرچم (Flags) شناخته میشود و بهصورت بیتی تفسیر میشوند. در استانداردهای گوناگون از 6 بیت تا نهایتا 9 بیت کم ارزش آن استفاده شده و مابقی بیت های پر ارزش، صفر (Zero) بوده و استفاده نمی شوند. بهمین دلیل ممکن است در نت، مواردی پیدا کنید که این بخش پرچم، بیت های بیشتری نسبت به تصویر قبلی داشته باشد؛ اما در تمامی آنها 6 بیت کم ارزش، بطور حتم وجود دارند که الزام استاندارد اولیه TCP هست. این بیت ها رو بطور جداگانه مورد بررسی قرار بدیم، ببینیم چی هستند :
FIN : یا پایان (Final)؛ هر گاه یک سمت ارتباط؛ داده دیگری برای ارسال نداشته باشه؛ این بیت رو یک میکنه. توجه داشته باشید که در اینجا ارتباط پایان نمیگیرد؛ چون ممکن است طرف مقابل همچنان دادههایی برای ارسال داشته باشد. همونطور که گفتیم برای قطع ارتباط بعد از اتمام ارسال داده از هر دو طرف؛ یک هندشیک 4 مرحلهای هم برای پایاندادن به ارتباط (Close) خواهیم داشت. ستشدن این بیت، نشاندهنده آغاز پروسه اتمام (close) در یک ارتباط است.
SYN : یا Synchron. هر گاه این بیت یک باشد؛ یعنی مقدار موجود در بخش Sequence Number مقدار اولیه (صفر یا آفست) را نشون میده! توجه داشته باشید که این بیت، تنها در مرحله یک و دو از هندشیک اولیه استفاده میشه و در این دو مرحله، هر طرف مقدار آفست خودش رو اعلام میکنه.
RST : یا Reset. از این بیت در هندشیک 4 مرحلهای در پایان ارتباط (Closing) استفاده میشه. هر گاه این بیت یک بشه؛ فرستنده این بیت بهطرف مقابل اعلام میکنه که ارتباط رو خاتمهیافته فرض میکنه و دیگه به پیغامهای طرف مقابل جواب نمیده.
PSH : مخفف Push است. گفتیم که در حالت عادی، هر سمت یک مقدار داده رو در سگمنتهای مختلف ارسال میکنه (مثلاً یک فایل بزرگ رو). پس در حالت عادی، گیرنده باید صبر کنه تا تمام دادهها رو بگیره و بعد از اون ها استفاده بکنه. ستکردن این بیت، بهطرف گیرنده میفهمونه که دیگه منتظر سگمنت بعدی نمونه و دادههایی که تا اینجا ارسال شده رو استفاده کنه.
Ack : بیت تأیید (Acknowledge). در استاندارد گفته شده، ست بودن این بیت در یک سگمنت، یعنی اینکه Ack Num واقع در سگمنت معتبر هست. بهطورکلی ستکردن این بیت، بهطرف دیگه میفهمونه اطلاعاتی دریافت شده؛ همین! و در واقع، جز در مرحله یک از هند شیک ابتدایی، در تمام سگمنتهای ارسالی بعدی، این بیت یک خواهد بود؛ به این معنی که پیام قبلی دریافت شده است!
URG : مخفف Urgent یا اضطراری؛ این بیت همراه با بخش Urgent Pointer استفاده میشه. هر گاه این بیت یک بشه؛ یعنی بخش Urgent Pointer حاوی اطلاعات بااهمیت هست. هر گاه در حین یک ارتباط نرمال؛ نیاز باشه که دادههایی بهصورت ضروری و بدون صبرکردن برای دریافت مابقی بایتها؛ مورد پردازش قرار بگیره؛ از این بخشها استفاده میشه. بذارید یه مثال بزنیم. فرض کنید مدار الکترونیکی شما یه برد کنترلی هست شامل یک سنسور دمای حساس بعلاوه چند سنسور و عملگر (رله، ولو Valve، لامپ) دیگه و برد در هر سگمنت، اطلاعات یک بخشی از سنسورها رو میفرسته و احتمالاً از سمت مقابل دستوراتی میگیره که کدام خروجیها رو فعال کنه. حالا سنسور دمای اصلی؛ یک دمای غیرعادی نشون میده، برد با یک کردن بیت URG و ارسال مقدار سنسور دما به طرف مقابل میفهمونه که یک حالت ضروری پیش اومده که نیاز به پردازش فوری داره. در نتیجه گیرنده این سگمنت رو به طور ویژهای پردازش میکنه و منتظر دریافت اطلاعات مابقی سنسورها نمی مونه.
Window Size : با استفاده از این بخش، هر طرف به طرف مقابل میگه که چقدر حافظه برای دریافت داده داره. بهتره که باز هم با یک مثال موضوع رو روشنتر کنیم. فرض کنید فرستنده در حال ارسال یک فایل بسیار حجیم هست. گیرنده برای دریافت؛ یک حافظه 10 کیلوبایتی در RAM اختصاص داده؛ ابتدا مقدار Window Size رو همون 10KB اعلام میکنه و هر بار با دریافت مقداری داده؛ مقدار window size رو کاهش میده و دادهها رو در رم خودش مینویسه؛ وقتی دیگه حافظهاش پر شد، window size رو صفر اعلام میکنه تا فرستنده کمی صبر کنه. بعد دادهها رو از رم به درون فایلی در hard disk منتقل میکنه و حالا دوباره به فرستنده مقدار window size رو 10KB اعلام میکنه تا فرستنده دوباره شروع به ارسال داده بکنه. توجه داشته باشید که تعداد زیادی از این بخشها در واقع تمهیدات لازم برای یک ارتباط مطمئن هستند و لزومی نداره کاربر از تمام اونها استفاده بکنه. ما هم از اونجایی که همواره در حال پردازش هستیم از این بخش و بعضی قابلیتهای دیگه TCP استفاده نخواهیم کرد مگر اینکه سرعت ارسال بالا باشه و میکروکنترلر عقب بمونه. در این حالت میتونید این بخش رو صفر اعلام کنید تا طرف مقابل کمی صبر کنه.
Check Sum : بخش چک سام. در اینجا هم مثل پروتکل UDP شامل هدر، دادهها و بخش شبه هدر (psudoHeader) هست. جهت یادآوری بخش شبه هدر از آدرسهای IP فرستنده/گیرنده، Zero+TCP protocol=0x0006 و اندازه طول سگمنت ارسالی هست. توجه داشته باشید که به دلیل بزرگبودن بخش محاسباتی و زمانبر بودن انجام این محاسبات؛ نیاز هست که یه کد سریع برای این کار نوشته بشه و یا در صورت امکان در سختافزار انجام بشه.
Urgent Pointer : یا اشارهگر به بخش ضروری. چنانچه نیاز باشه که دادهها بهصورت ضروری (با اولویت بالا و بدون انتظار برای رسیدن مابقی اطلاعات) پردازش بشن، بیت URG که بالاتر معرفی کردیم، ست میشه؛ دادههای ضروری در ابتدای بخش دادهها نوشته و ارسال میشن و در این قسمت، آدرس آخرین بایت بخش Urgnet قرار میگیره تا گیرنده متوجه بشه که دادهای ضروری از ابتدا تا کجای بخش دادهها هستند. بقیه داده هم که داده عادی تلقی خواهند شد؛ بعد از بخش urgent نوشته میشن. برای مثال فرض کنید سگمنت فعلی؛ بخش option نداره و دادهها از بایت بیست و یکم به بعد در یک سگمنت نوشته شدهاند. حالا فرض کنید تعداد 10 بایت، داده ضروری داریم. بیت URG ست میشه و در این قسمت عدد 10 نوشته میشه به این معنی که از بایت 21 تا 30 شامل دادههای ضروری هست و دادههای عادی از بایت سی و یکم به بعد نوشته شدهاند.
Options : یا بخش گزینهها. این بخش چنانچه وجود داشته باشد؛ باید اندازه آن مضربی از 4 باشه؛ چون طول آن برحسب کلمات 4بایتی (DWORD) محاسبه و اندازه آن به بخش Header Length اضافه میشه. در صورتی که اندازه بخش Option مضربی از 4 نباشد، در انتهای آن بایت هایی با مقدار 0x00 اضافه میشود (padding).
در استاندارد TCP تعداد زیادی گزینه (Option) معرفی شده است؛ همچنین گزینههایی در حال بهینهسازی و استفاده خصوصی هستند که ممکنه در آینده به استاندارد اضافه بشه. اما یک هاست، طبق الزام استاندارد، حداقل باید تعداد خاصی از آنها را پشتیبانی (support) نماید.
همانطور که در بخش UDP و مبحث TLV گفتیم؛ بهطورکلی گزینهها دو حالت دارند:
در ادامه تعدادی از مهمترین گزینهها رو بررسی میکنیم.
MSS= Maximum Segment Size.
Type=0x02, Length=0x04, Value=2Bytes
آپشن نوع 2 ؛ چهار بایتی هست، از این آپشن برای اینکه به طرف مقابل بفهمانیم در هر سگمنت حداکثر چه تعداد بایت میتواند ارسال کند، استفاده میشود. این آپشن فقط در دو مرحله ابتدایی هندشیک اولیه (مراحل SYN) میتواند وجود داشته باشد. از آنجایی که برای مقدار MSS دو بایت در نظر گرفته شده؛ حداکثر سایز داده ارسالی 65535 بایت هست.
WS= Window Scale.
Type=0x03, Length=0x03, Value=1Byte
در هدر بخشی با نام Window Size وجود داشت که هر طرف به طرف مقابل میفهماند که چقدر حافظه دیگر برای دریافت اطلاعات دارد. این بخش دوبایتی بود؛ لذا حداکثر عدد داخل آن 65535 میتواند باشد. چنانچه هاستی، دارای مقدار بزرگتری حافظه باشد؛ از گزینه WS برای بزرگتر کردن مقدار window size میتونه استفاده کنه. همانطور که در تعریف این گزینه دیده میشود؛ این گزینه یک بایتی است و عدد داخل آن بهصورت توانی از 2 تفسیر میشود. فرض کنید ws=4 و window size= 1024 باشد، اندازه اصلی window size برابر با 16384 بایت خواهد بود:
SACK Permit= Selective Acknowledge Permit.
Type=0x04,Length=0x02 without value.
SACK = Selective Acknowledge.
Type=0x05,Length=10,18,26 or 34
این دو گزینه معمولاً با هم استفاده میشوند. یادتون باشه گفتیم سگمنتها همراه با Seq Num ارسال میشن. فرض کنید، در حال ارسال یک فایل 10 کیلو بایتی در سگمنتهای 1 کیلوبایتی هستیم. سگمنتهای اول و دوم و چهارم به بعد بهدرستی در گیرنده دریافت شدهاند؛ اما سگمنت سوم به دلایلی به مقصد نرسیده است. در استاندارد اولیه که این گزینه وجود نداشت؛ گیرنده، در قسمت Ack Num تنها میتوانست دریافت دادهها تا انتهای سگمنت دوم را تأیید کند و فرستنده مجبور بود که سگمنتهای سوم تا دهم رو مجدد ارسال کنه (retransmission) اما در سال 1996 و در سند RFC 2018 این گزینه معرفی و مورداستفاده قرار گرفت. هدف، حل این ایراد بود. طرفی که قادر به پذیرش SACK هست؛ در مرحله هندشیک اولیه (مرحله SYN) آن را با استفاده از گزینه SACK Permit=0x04 اعلام میکند و طرف مقابل چنانچه بخواهد از این قابلیت استفاده کند؛ حداکثر میتواند چهار SACK داشته باشد. در مثال بالا یک SACK برای سگمنتهای اول و دوم و یک SACK برای سگمنتهای چهارم تا دهم استفاده خواهد شد (دو SACK). در نتیجه فرستنده داده، متوجه فقدان SACK برای سگمنت سوم شده و تنها آن را باز ارسال خواهد کرد. همانطور که دیده میشود (بخش اندازه رو ببینید) برای هر SACK، هشت بایت در نظر گرفته شده است. چهار بایت برای شروع و چهار بایت برای اعلام پایان هر SACK. در واقع با استفاده از این قابلیت، دیگه نیاز نیست برای هر سگمنت یک ACK جداگانه ارسال بشه. برای اطلاع از مابقی گزینهها به اسناد RFC مراجعه و یا در نت جستجو کنید.
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.