فصل ۱۶: معماری شبکه، آدرسها، پورتها و URIها در .NET
فصل ۱۶: معماری شبکه، آدرسها، پورتها و URIها در .NET
فروش یا انتشار این ترجمه منوط به داشتن مجوز لازم از صاحب حقوق اثر است.
۱۶ — شبکهسازی (Networking)
.NET مجموعهای از کلاسها را در فضاهای نام System.Net.* برای ارتباط از طریق پروتکلهای استاندارد شبکه، مانند HTTP و TCP/IP، ارائه میکند. در ادامه خلاصهای از مؤلفههای اصلی آمده است:
HttpClient برای مصرف APIهای وب HTTP و سرویسهای RESTfulHttpListener برای نوشتن یک سرور HTTPSmtpClient برای ساخت و ارسال پیامهای ایمیل از طریق SMTPDns برای تبدیل بین نامهای دامنه و آدرسها- کلاسهای
TcpClient، UdpClient، TcpListener و Socket برای دسترسی مستقیم به لایههای انتقال و شبکه
نوعهای .NET در این فصل در فضاهای نام System.Net.* و System.IO قرار دارند.
معماری شبکه (Network Architecture)
شکل 16-1 نوعهای شبکهسازی .NET و لایههای ارتباطیای را که این نوعها در آن قرار میگیرند نشان میدهد. بیشتر نوعها در لایهٔ انتقال (transport layer) یا لایهٔ کاربرد (application layer) قرار دارند. لایهٔ انتقال پروتکلهای پایه برای ارسال و دریافت بایتها، یعنی TCP و UDP، را تعریف میکند؛ لایهٔ کاربرد پروتکلهای سطح بالاتری را تعریف میکند که برای کاربردهای مشخص طراحی شدهاند؛ مانند دریافت صفحات وب با HTTP، ارسال ایمیل با SMTP و تبدیل بین نام دامنه و آدرس IP با DNS.
شکل 16-1 — معماری شبکه
معمولاً برنامهنویسی در لایهٔ کاربرد راحتتر است؛ با این حال، چند دلیل وجود دارد که ممکن است بخواهید مستقیماً در لایهٔ انتقال کار کنید. یکی زمانی است که به یک پروتکل کاربردی نیاز دارید که .NET آن را فراهم نکرده است؛ برای نمونه POP3 برای دریافت ایمیل. دلیل دیگر زمانی است که میخواهید برای کاربرد خاصی، مانند یک کلاینت همتابههمتا (peer-to-peer)، پروتکل سفارشی خودتان را ابداع کنید.
در میان پروتکلهای کاربردی، HTTP از نظر قابلیت استفاده برای ارتباطات عمومی جایگاه ویژهای دارد. شیوهٔ پایهٔ کار آن — «صفحهٔ وب با این URL را به من بده» — بهخوبی به «نتیجهٔ فراخوانی این endpoint با این آرگومانها را به من بده» تعمیم پیدا میکند. افزون بر فعل GET، افعال PUT، POST و DELETE نیز وجود دارند و سرویسهای مبتنی بر REST را ممکن میکنند.
HTTP همچنین مجموعهٔ غنیای از قابلیتها دارد که در برنامههای تجاری چندلایه و معماریهای سرویسگرا مفیدند؛ از جمله پروتکلهای احراز هویت و رمزنگاری، قطعهبندی پیام (message chunking)، هدرها و کوکیهای قابل گسترش، و امکان اشتراک یک پورت و آدرس IP میان چند برنامهٔ سرور. به همین دلایل، HTTP در .NET بهخوبی پشتیبانی میشود؛ هم مستقیماً، همانگونه که در این فصل توضیح داده میشود، و هم در سطح بالاتر از طریق فناوریهایی مانند Web API و ASP.NET Core.
همانطور که بحث پیشین روشن میکند، شبکهسازی حوزهای سرشار از مخففها است. متداولترین آنها در جدول 16-1 فهرست شدهاند.
جدول 16-1 — مخففهای شبکه| مخفف | عبارت کامل | توضیح |
|---|
| DNS | Domain Name Service | تبدیل بین نامهای دامنه، مانند ebay.com، و آدرسهای IP، مانند 199.54.213.2. |
| FTP | File Transfer Protocol | پروتکل مبتنی بر اینترنت برای ارسال و دریافت فایلها. |
ادامهٔ جدول 16-1 — مخففهای شبکه| مخفف | عبارت کامل | توضیح |
| HTTP | Hypertext Transfer Protocol | صفحات وب را دریافت میکند و سرویسهای وب را اجرا میکند. |
| IIS | Internet Information Services | نرمافزار وبسرور مایکروسافت. |
| IP | Internet Protocol | پروتکل لایهٔ شبکه در زیر TCP و UDP. |
| LAN | Local Area Network | بیشتر LANها از پروتکلهای مبتنی بر اینترنت مانند TCP/IP استفاده میکنند. |
| POP | Post Office Protocol | ایمیل اینترنتی را دریافت میکند. |
| REST | REpresentational State Transfer | یک معماری محبوب سرویس وب که از لینکهای قابلپیگیری توسط ماشین در پاسخها استفاده میکند و میتواند روی HTTP پایه کار کند. |
| SMTP | Simple Mail Transfer Protocol | ایمیل اینترنتی را ارسال میکند. |
| TCP | Transmission and Control Protocol | پروتکل اینترنت در لایهٔ انتقال که بیشتر سرویسهای لایههای بالاتر بر روی آن ساخته شدهاند. |
| UDP | Universal Datagram Protocol | پروتکل اینترنت در لایهٔ انتقال برای سرویسهای کمهزینه مانند VoIP. |
| UNC | Universal Naming Convention | \\computer\sharename\filename |
| URI | Uniform Resource Identifier | سامانهٔ نامگذاری فراگیر منابع؛ برای مثال http://www.amazon.com یا mailto:joe@bloggs.org. |
| URL | Uniform Resource Locator | معنای فنی، که استفاده از آن رو به کاهش است: زیرمجموعهای از URI؛ معنای رایج: مترادف URI. |
آدرسها و پورتها (Addresses and Ports)
برای اینکه ارتباط برقرار شود، یک رایانه یا دستگاه به آدرس نیاز دارد. اینترنت از دو سامانهٔ آدرسدهی استفاده میکند:
- IPv4
- در حال حاضر سامانهٔ آدرسدهی غالب است؛ آدرسهای IPv4 عرضی برابر با 32 بیت دارند. در قالب رشتهای، آدرسهای IPv4 به شکل چهار عدد دهدهی جداشده با نقطه نوشته میشوند، مانند
101.102.103.104. یک آدرس میتواند در سراسر جهان یکتا باشد یا فقط در یک زیرشبکهٔ خاص، مانند شبکهٔ یک شرکت، یکتا باشد. - IPv6
- سامانهٔ آدرسدهی جدیدتر و 128 بیتی است. آدرسها به شکل هگزادسیمال با جداکنندهٔ دونقطه قالببندی میشوند؛ برای مثال
[3EA0:FFFF:198A:E4A3:4FF2:54fA:41BC:8D31]. .NET از شما میخواهد براکتهای مربع را پیرامون آدرس قرار دهید.
کلاس IPAddress در فضای نام System.Net یک آدرس را در هر یک از این دو پروتکل نمایش میدهد. این کلاس سازندهای دارد که آرایهٔ بایت میپذیرد و یک متد ایستای Parse دارد که رشتهای با قالب صحیح را میپذیرد:
IPAddress a1 = new IPAddress (new byte[] { 101, 102, 103, 104 });
IPAddress a2 = IPAddress.Parse ("101.102.103.104");
Console.WriteLine (a1.Equals (a2)); // True
Console.WriteLine (a1.AddressFamily); // InterNetwork
IPAddress a3 = IPAddress.Parse
("[3EA0:FFFF:198A:E4A3:4FF2:54fA:41BC:8D31]");
Console.WriteLine (a3.AddressFamily); // InterNetworkV6
پروتکلهای TCP و UDP هر آدرس IP را به 65,535 پورت تفکیک میکنند و به این ترتیب یک رایانه با یک آدرس میتواند چند برنامه را اجرا کند که هر کدام پورت خود را دارند. بسیاری از برنامهها شمارهپورتهای پیشفرض استاندارد دارند؛ برای نمونه HTTP از پورت 80 و SMTP از پورت 25 استفاده میکند.
ترکیب یک آدرس IP و یک پورت در .NET با کلاس IPEndPoint نمایش داده میشود:
IPAddress a = IPAddress.Parse ("101.102.103.104");
IPEndPoint ep = new IPEndPoint (a, 222); // Port 222
Console.WriteLine (ep.ToString()); // 101.102.103.104:222
URIها
URI رشتهای با قالب ویژه است که یک منبع در اینترنت یا LAN، مانند صفحهٔ وب، فایل یا آدرس ایمیل، را توصیف میکند. نمونهها شامل http://www.ietf.org، ftp://myisp/doc.txt و mailto:joe@bloggs.com هستند. قالب دقیق توسط Internet Engineering Task Force یا IETF تعریف شده است.
یک URI را میتوان به مجموعهای از اجزا — معمولاً scheme، authority و path — تقسیم کرد. کلاس Uri در فضای نام System دقیقاً همین تفکیک را انجام میدهد و برای هر جزء یک property در اختیار میگذارد، همانگونه که در شکل 16-2 نشان داده شده است.
شکل 16-2 — ویژگیها و اجزای URI
میتوانید با ارسال هر یک از رشتههای زیر به سازندهٔ Uri یک شیء Uri بسازید:
- یک رشتهٔ URI، مانند http://www.ebay.com یا file://janespc/sharedpics/dolphin.jpg.
- یک مسیر مطلق به فایلی روی دیسک سخت، مانند
c:\myfiles\data.xlsx یا در Unix، مسیر /tmp/myfiles/data.xlsx. - یک مسیر UNC به فایلی روی LAN، مانند
\\janespc\sharedpics\dolphin.jpg.
مسیرهای فایل و UNC بهطور خودکار به URI تبدیل میشوند: پروتکل file: افزوده میشود و backslashها به slash رو به جلو تبدیل میشوند. سازندههای Uri همچنین پیش از ساخت شیء، پاکسازیهای پایهای روی رشته انجام میدهند؛ از جمله تبدیل scheme و hostname به حروف کوچک و حذف شمارهپورتهای پیشفرض یا خالی. اگر یک رشتهٔ URI بدون scheme، مانند www.test.com، ارائه کنید، یک UriFormatException رخ میدهد.
Uri دارای propertyای به نام IsLoopback است که مشخص میکند آیا URI به میزبان محلی با آدرس IP 127.0.0.1 اشاره دارد یا نه؛ و propertyای به نام IsFile دارد که تعیین میکند آیا URI به یک مسیر محلی یا UNC اشاره میکند. IsUnc برای یک share از نوع Samba که در فایلسیستم Linux mount شده باشد مقدار false گزارش میکند. اگر IsFile مقدار true برگرداند، property LocalPath نسخهای از AbsolutePath را برمیگرداند که با سیستمعامل محلی سازگار است — با slash یا backslash مناسب همان سیستمعامل — و میتوانید File.Open را روی آن فراخوانی کنید.
نمونههای Uri propertyهای فقطخواندنی دارند. برای تغییر یک Uri موجود، یک شیء UriBuilder بسازید؛ propertyهای آن قابل نوشتناند و از طریق property Uri میتوان آن را دوباره به Uri تبدیل کرد.
Uri همچنین متدهایی برای مقایسه و تفریق مسیرها ارائه میکند:
Uri info = new Uri ("http://www.domain.com:80/info/");
Uri page = new Uri ("http://www.domain.com/info/page.html");
Console.WriteLine (info.Host); // www.domain.com
Console.WriteLine (info.Port); // 80
Console.WriteLine (page.Port); // 80 (Uri knows the default HTTP port)
Console.WriteLine (info.IsBaseOf (page)); // True
Uri relative = info.MakeRelativeUri (page);
Console.WriteLine (relative.IsAbsoluteUri); // False
Console.WriteLine (relative.ToString()); // page.html