TCP و HTTP

TCP چیست و چرا Handshake؟

TCP پروتکل انتقال قابل‌اعتماد در لایه‌ی Transport است. برخلاف UDP که بسته‌ها را همین‌طور رها می‌کند و می‌فرستد، TCP قبل از هر تبادل واقعی داده، یک Handshake سه‌مرحله‌ای انجام می‌دهد: SYN, SYN-ACK, ACK. در همین سه گام، دو طرف شماره‌ترتیب بسته‌ها را با هم هماهنگ می‌کنند؛ از آن پس TCP تضمین می‌کند بسته‌ها به همان ترتیب برسند و اگر چیزی گم شد، دوباره فرستاده شود.

برای کار DevOps این Handshake یک نقطه‌ی طلایی در عیب‌یابی است: اگر اتصال TCP اصلاً برقرار نمی‌شود، مشکل قطعاً قبل از هر چیز دیگری است — یک فایروال، سرویسی که خاموش است یا یک مشکل دیگر. پس اگر TCP وصل نشود، برنامه حتی فرصت نمی‌کند خطا هم بدهد.

HTTP: درخواست و پاسخ

HTTP پروتکل سطح Application است: کلاینت یک درخواست (Request) می‌فرستد و سرور با یک پاسخ (Response) جواب می‌دهد. درخواست از این تکه‌ها ساخته شده:

  • Method: قصد شما را می‌گوید — GET برای خواندن، POST برای ایجاد، PUT/PATCH برای به‌روزرسانی و DELETE برای حذف
  • Path و نسخه‌ی پروتکل: مانند GET / HTTP/1.1
  • Headers: متادیتای درخواست — Host، User-Agent، Accept و مواردی از این دست
  • Body (اختیاری): داده‌ی همراه درخواست — در POST و PUT معمولاً هست

پاسخ هم همیشه یک کد وضعیت با خودش می‌آورد:

  • 2xx موفق — مانند 200 OK
  • 3xx جابه‌جایی — مانند 301 (دائمی) و 302 (موقت)
  • 4xx خطای سمت کلاینت — مانند 404 Not Found و 403 Forbidden
  • 5xx خطای سمت سرور — مانند 500 و 502 Bad Gateway؛ در عیب‌یابی سرویس‌های پشت Proxy این کد را زیاد خواهید دید

تست پورت با nc

قبل از این‌که سراغ ابزارهای سطح Application برویم، با nc می‌توانید بفهمید آیا TCP اصلاً باز است یا نه:

1nc -zv 127.0.0.1 22
2nc -zv 127.0.0.1 80
  • -z فقط چک می‌کند چیزی گوش می‌دهد یا نه، بدون این‌که واقعاً داده بفرستد.
  • -v نتیجه را برایتان چاپ می‌کند؛ پیام Connection succeeded یعنی TCP جواب داده است.

اگر بخواهید عمیق‌تر بروید، می‌توانید یک درخواست خام را با دست تایپ کنید و HTTP را بدون هیچ مرورگری ببینید. با nc example.com 80 وصل شوید، این را بنویسید و دو بار Enter بزنید:

1GET / HTTP/1.1
2Host: example.com

پاسخ خامِ HTTP همان‌جا در ترمینال ظاهر می‌شود، هم Headers و هم Body.

دیدن درخواست کامل با curl -v

curl -v هم TCP Handshake و هم کل تبادل HTTP را نشان می‌دهد و به همین دلیل یکی از رایج‌ترین ابزار عیب‌یابی سرویس‌های وب است:

1curl -v http://example.com/
2curl -v http://example.com/missing
3curl -v -I http://example.com/
  • خط‌های شروع‌شده با > چیزی است که شما فرستادید، و < پاسخی است که سرور برگردانده.
  • خط Connected to دقیقاً همان نقطه‌ای است که TCP موفق شده.
  • گزینه‌ی -I فقط هدرها را می‌گیرد (با متد HEAD) — راه سریعی برای دیدن فقط کد وضعیت، بدون دانلود کامل صفحه.

تمرین

  1. سرویس SSH را روشن کنید و با nc -zv 127.0.0.1 22 وضعیتش را چک کنید. بعد سرویس را متوقف کنید و همان دستور را دوباره بزنید — پیام Connection refused را با پیام موفقیت قبلی مقایسه کنید.
  2. یک درخواست خام با nc به example.com بفرستید و خط Status پاسخ را در خروجی پیدا کنید.
  3. همین دو مورد را با curl -v هم اجرا کنید و در خروجی سه لایه را از هم جدا کنید: Handshake، Headers درخواست و کد وضعیت پاسخ.

آخرین قدم، همان چیزی است که بعداً در عیب‌یابی واقعی زیاد به کارتان می‌آید: وقتی nc -zv یک پورت را «باز» گزارش می‌کند اما curl -v همچنان خطا می‌دهد، این یعنی مشکل از TCP نیست — چون تا همین‌جا موفق شده — بلکه خودِ برنامه یا HTTP روی آن پورت درست کار نمی‌کند. جدا کردن همین دو حالت، بخش زیادی از سردرگمی عیب‌یابی را از بین می‌برد.

منابع یادگیری

مستندات و مقالات

ویدیو