در مقاله قبل علاوه بر آشنایی با قسمتهای مختلف پروتکلTCP ، فهمیدیم که در آغاز یک کانکشن TCP ابتدا دو طرف کانکشن Three way handshake را انجام میدهند که با کمک بیت های کنترلی SYN و ACK انجام میشود و همینطور در پایان یک Session هر دو peer با استفاده از بیت کنترلی FIN کانکشن را پایان داده و حافظه اختصاص داده شده به آن کانکشن را آزاد میکنند.
اما در این مقاله قصد داریم مبحثی را بررسی کنیم که نشان می دهد دو طرف کانکشن چگونه جریان داده را کنترل میکنند که در TCP معروف به Flow Control میباشد.
همان طور که می دانیم خاصیت یک کانکشنی از جنس Connection Oriented این است که اگر در حین Transfer Data بسته های درون کانکشن به دلایل مختلف مانند ازدحام یا Congestion از بین رفتند هیچ رسید یا ACK از طرف مقابل دریافت نمیشود و فرستنده مجبور به ارسال دوباره بسته است بر خلاف پروتکل UDP
کنترل جریان در TCP به کمک window صورت میگیرد که البته درTCP دو پنجره تعریف شده است.
RWND
CWND
منظور از Rwnd همان Receive Window یا Advertised Window میباشد.
یعنی چی؟؟!!
وقتی کانکشن Established می شود هر دو Peer یک بافر (یا صف با طول مشخص) برای آن کانکشن رزرو می کنند که بسته های دریافتی و ارسالی در این صف قرار می گیرند و البته مقدار، مشخص می باشد و بسته به نیاز در Application قابل تغییر است.
در حین ارسال و دریافت Data هر دو طرف کانکشن هم دیگر را از مقدار فضای خالی بافر خود با خبر می کنند که فرستنده بسته های ارسالی خود را کنترل کند و اگر بافر گیرنده در حداکثر ظرفیت باشد یا پر باشد بسته های دریافتی را گیرنده بیرون میریزد و رسید آن بسته ها را به فرستنده نمی دهد و فرستنده مجبور به ارسال دوباره می شود.
مقدار فضای خالی بافر در هر دو طرف توسط فیلد Window درهدر TCP به طرف مقابل اعلام میشود که بر حسب بایت است.
خب با این تفاسیر یعنی فرستنده هنگام ارسال بسته ها نگاه به مقدار فضای خالی بافر طرف مقابل می کند یا بهتر بگیم نگاه به Rwnd میکند و Segment ها را بر آن اساس ارسال می کند؟!
بریم یه نقض پیدا کنیم، فرض کنید سایز بافر گیرنده در بهترین حالت ممکن یعنی خالی می باشد و فرستنده سگمنت ها را بر این اساس با نرخ بالا ارسال کند و به ازای هر سگمنت Ack دریافت نکند وبه ازای Window رسید یا ACK دریافت کند اگر شبکه ازدحام داشته باشد و سگمنت ها در طول مسیر و یا در روترها به علت نبود پهنای باند از بین بروند چه اتفاقی می افتد؟؟!
در این حالت فرستنده فقط ظرفیت بافر گیرنده را هنگام ارسال در نظر گرفته و کاری به ظرفیت شبکه و مسیر نداشته است!!
پس این چه جور Flow Control ای می باشد؟؟!
باید کاری کرد فرستنده علاوه بردر نظر گرفتن فضای خالی بافر گیرنده، ظرفیت شبکه را نیز در نظر بگیرد.
این کار را به کمک Cwnd انجام میشود.
قبل از این که شروع به بررسی Cwnd کنیم با یک سری از Time ها آشنا بشیم که اساس TCP این زمانسنج ها میباشد.
یک سوال
فرستنده تا چه زمان منتظر بسته Ack از گیرنده باشد؟!
فرض کنید فرستنده سگمنت های ۱۰۰ تا ۱۱۰ را بر اساس سایز پنجره ارسال کرد تا چه مدت منتظر دریافت ACK این سگمنت ها می شود و بعد از چه مدتی متوجه می شود که بلایی سر بسته ها آمده است؟!
یک سوال دیگر
مقدار زمانی که طول میکشد بسته Ack گیرنده به ما برسد همیشه ثابت است؟! یعنی مدت زمانی که فرستنده صبر میکند برای دریافت Ack ، در تمام شبکه ها یکسان است؟ یعنی یک بسته اگر بخواهد به ما برسد طول مسیر اهمیت دارد یا نه؟
یعنی Delay در شبکه LAN و شبکه های اینترنت یا خصوصی یکسان است؟!
صد در صد فرق دارد.
ممکن است مدت زمان ۱۰ میلی ثانیه انتظار، برای فرستنده برای در نظر گرفتن Timeout شدن بسته در LAN که هیچ روتری بسته های ما را Route نمیکند مناسب باشد ، ولی در شبکه اینترنت بسیار کم است زیرا ده ها روتر بسته های ما را Route می کنند برای رسیدن به مقصد و می دانیم به ازای هر بار روت شدن بسته در روتر یک مقدار Delay وجود دارد .
جا به جا شدن بسته در شبکه LAN بسیار سریع است نسبت به شبکه WAN .
فرستنده به ازای ارسال هر سگمنت یک زمانسنج را Start می کند تا زمانی که ACK آن را دریافت کند.
RTT متوسط یا Round Trip Time مدت زمانی است که یک بسته میرود و ACK آن می آید هر Peer این زمان را به ازای هر سگمنت ارسالی اندازه گیری میکنند.
علاوه بر آن یک RTT پراکندگی نیز در نظر میگیرد (وضعیت شبکه همیشه ثابت نیست و مدام در حال تغییر است)
دقت داشته باشید منظور از SRTT در فرمول ها و کتاب ها Sample RTT است.
این دو زمان را در یک فرمولی قرار میدهد تا RTO را محاسبه میکند. (Retransmission Timeout)
(SRTT = RTT + 8*(New_RTT – RTT
Dev = Dev + (|New_RTT – RTT| – Dev)/4
RTO = SRTT + Dev/4
نکته:
اگر دستگاه گیرنده به کل از بین رفته باشد (خاموش شود) یا در شبکه اختلال دائمی باشد فرستنده تا همیشه ارسال میکند؟!!
علاوه بر Timeout به ازای هر سگمنت ، خود کانکشن یک Timeout دارد یعنی اگر Peer مقابل جواب فرستنده را ندهد فرستنده تا همیشه کانکشن را باز نگه نمیدارد ابتدا کانکشن از Established به Time-Wait تغییر وضعیت میدهد و بعد از زمانی به Close-Wait و سپس کانکشن را یک طرفه می بندد.
حالا بریم سر مبحث Cwnd
Congestion Window یا Cwnd طول پنجره ازدحام است و قرار است ظرفیت شبکه را در نظر بگیرد. و مانند شیر آب عمل میکند که با درجه بندی، جریان را کنترل مینماید.
مقدار این پنجره کاملا Locally است و از Peer مقابل به ارث نمیبرد.
حال چگونه محاسبه میشود؟
در ابتدای کانکشن، فرستنده مقدار پنجره ازدحام یا همان Cwnd را برابر با یک MSS قرار میدهد اگر ACK بسته آمد مقدار آن را ۲MSS قرار میدهد و باز اگر ACK آمد آنرا به ۴MSS افزایش میدهد این عمل تکرار میشود و Cwnd را به صورت نمایی بالا میبرد.
نکته مهم:
مقدار نهایی Window برابر با (Min(Rwnd , Cwnd
یعنی فرستنده هنگام ارسال هم ظرفیت گیرنده را در نظر میگیرد و هم مقدار Cwnd خود را که نمایی بالا میبرد و از این دو مقدار Min گرفته و سایز پنجره را اینگونه تعیین میکند.
سوال
مقدار Cwnd تا چه مقدار بالا میرود؟؟
فرض کنید مقدار Cwnd برابر با ۳۲MSS شده است و رسید یا Ack را فرستنده از گیرنده دریافت میکند و گیرنده در این بسته به فرستنده مقدار فضای خالی بافر خود را یا همان Rwnd را به فرستنده اعلام میکند حال فرستنده مقدارCwnd خود را ۶۴MSS میکند و min میگیرد از Cwnd و Rwnd و مقدار پنجره را به دست آورده و با آن نرخ سگمنت ها را ارسال میکند و زمانسنج را Start میکند ولی رسید بسته ها را دریافت نمی کند ، در این لحظه مقدار Cwnd جدید برابر است با کمترین مقدار یعنی ۱MSS و برای خود حد آستانه یا ssthresh که معادل Slow-Start Threshold است ، مشخص میکند که برابر است با آخرین Cwnd تقسیم بر ۲ یعنی ۳۲MSS و هنگام ارسال دوباره مقدار Cwnd را تا نزدیک ssthresh نمایی بالا میبرد که تا این مرحله را Slow-Start مینامند و بعد از عبور از ssthresh مقدار Cwnd را خطی بالا میبرد، که به این مرحله تا Slow-Start بعدی Congestion Avoidance میگویند یا همان پیشگیری از ازدحام.
منظور از Slow-Start چیست ؟!
یعنی در ابتدا مقدار Cwnd را کمترین مقدار قرار میدهد و شروعی آهسته دارد (یک MSS) و نمایی بالا میرود و با اولین Timeout مقدار Cwnd سقوط میکند دوباره روی کمترین مقدار.
منظور از Congestion Avoidance چیست ؟!
زیرا با تجربه ای که از قبل به دست آورده اگر بخواهد مقدار Cwnd را به صورت نمایی بالا ببرد احتمال اینکه دوبار Congestion صورت گیرد و بسته ها تلف شوند بسیار است به همین دلیل بعد از عبور از Last Cwnd/2 مقدار Cwnd را خطی زیاد میکند و اگر دوبار Timeout صورت گیرد برمیگردد به حالت Slow-Start
می توان نتیجه گرفت که اگر مقدار بافر گیرنده پایین باشد یا وضعیت شبکه در شرایط مساعد نباشد و بسته ها در طول مسیر Delay بخورند یا Loss شوند دو طرف کانکشن، خود را با این شرایط تطبیق میدهند و یک کانکشن Stable را برقرار میکنند ولی با سرعت پایین تر.
باز تاکیید میکنم که اندازه نهایی پنجره برابر است با (Min(RWND , CWND
حالا با دقت به نمودار زیر توجه کنید:
حالا نمودار تاثیر Slow-Start و Congestion Avoidance رو نرخ انتقال:
با توجه به اهمیت TCP به کنترل جریان به مرور زمان الگوریتم های مختلفی برای کنترل ازدحام و حتی پیشگیری با درصد بالا طراحی شده است مانند TCP Reno , TCP New Reno , TCP Tahoe و Vegas که سعی بر این دارند با استفاده از مکانیزم های Fast Recovery و Fast Retransmission تا حد امکان از ازدحام جلوگیری کنند که امیدوارم در مقاله های بعدی این مورد هم بررسی کنیم.
با این حال می توان تا اندکی تفاوت TCP Reno و TCP Tahoe را با این نمودار نمایش داد.
اگر به نمودار زیر دقت کنید میتوانید تفاوت دو پروتکل TCP وUDP را در گرفتن پهنای باند را مشاهده کنید.
UDP رشد میکند و سپس در بالاترین مقدار ثابت می ماند با پراکندگی اندک ولی TCP پروتکل حریصی می باشد و بعد از Slow-Start و Congestion Avoidance های پی در پی به نرخ ثابت با پراکندگی کمی رسیده است.(این مقایسه در حالت عدم رقابت برای گرفتن پهنای باند در دو پروتکل انجام شده).
اگرعلاقه به محاسبه بالاترین نرخ انتقال یا بازده (Throughput) در TCP هستید می توانید از فرمول زیر استفاده کنید.(فرمول به صورت دقیق نیست)
به کمک نمودار زیر میتوان رابطه Throughput با Loss شدن بسته را مشاهده کنید.
با پایین آمدن سرعت انتقال احتمال Loss شدن بسته ها کمتر میشود.
این هم از پرونده پروتکل محبوب و پر دردسر TCP .
با ITNovin همراه باشید.
ye kami sangin bood vali doost dashtam sepasgozaram