آموزش مقدماتی برنامه نویسی شبکه در سی شارپ (#C)

سلام عرض میکنم خدمت تمامی دوستان عزیز و امیدوارم که حالتون خوب باشه…
توی این مقاله آموزشی قراره که با برنامه نویسی شبکه در C# آشنایی پیدا کنید. توی این آموزش ما قصد داریم که با کلاس های TcpClient و NetworkStream و TcpListener و IPAddress آشنا بشیم.
از اونجایی که همینطوری هم مقاله طولانی میشه، متاسفانه نمیتونیم با کلاس Socket کار کنیم… اما در همین حد بدونید که Socket یک انتزاع از اتصاله که هم میتونه UDP باشه و هم TCP و…
بسیار خب پس تا آخر این مقاله با ما همراه باشید.
کلاس IPAddress
این کلاس حاوی یک آدرس IP در شبکه می باشد… سازنده های این کلاس متاسفانه هیچ ورودی رشته ای با فرمتی مانند 192.168.1.1 قبول نمیکنند.
برای این که بتوانید یک آدرس IP رشته ای را به صورت یک شی از کلاس IPAddress در بیاورید؛ میتوانید از متد استاتیک Parse استفاده کنید که به صورت ورودی یک آدرس IP رشته ای می پذیرد که میتواند IPV4 یا IPV6 باشد. اگر آدرس ورودی معتبر نباشد خطا رخ می دهد در غیر اینصورت یک IPAddress بر میگرداند.
این کلاس همچنین شامل متد های استاتیک HostToNetworkOrder و NetworkToHostOrder می باشد که وظیفه آنها به ترتیب این است که که ترتیب بایت های اعداد بیش از دو بایت را به حالت شبکه در بیاورد و اعداد حالت شبکه را به اعداد سیستم فعلی تبدیل کند.
برخی از سیستم ها بایت با ارزش را در اول قرار می دهند و برخی در آخر…. بنابرین ما باید در شبکه یک ترتیب داشته باشیم که بعدا به مشکلی بر نخوریم.
کلاس TcpClient
از این کلاس برای برقراری یک اتصال در شبکه استفاده میکنیم. همچنین با استفاده از NetworkStream میتوانیم داده ها را ارسال و دریافت کنیم. این کلاس یک ارتباط مطمئن برای تبادل اطلاعات را در اختیار ما قرار می دهد(با استفاده از پروتکل TCP)؛ در واقع هنگامی که داده ای را میخواهید ارسال کنید شما مطمئن هستید که داده ارسال می شود و اگر نشد خطا رخ می دهد(مثلا اگر اتصال قطع شود).
در UDP حتی اگر داده ارسال نشود باز هم برنامه به کار خودش ادامه می دهد. حتی اگر ترتیب داده ها به هم بریزد باز هم به کارش ادامه می دهد.
حالا که با TCP و UDP آشنایی پیدا کردیم، روش اتصال به یک سرور رو براتون شرح میدم :
برای این کار باید بعد از ساخت یک نمونه از این کلاس باید متد Connect استفاده کنیم که در ورودی اول یک IPAddress و در ورودی دوم یک شماره Port می پذیرد. اگر سرور در حال شنود روی پورت ارسالی باشد برنامه به حالت وقفه می رود. زمانی که اتصال رد شود یا از زمان خاصی بگذرد یک استثناء رخ می دهد. اگر اتصال قبول شود برنامه آماده ارسال و دریافت اطلاعات می شود.
برای بستن یک اتصال میتوانید از متد Close استفاده کنید. همچنین برای اینکه زمان ارسال را تعیین کنید میتوانید از SendTimeout استفاده کنید و برای تعیین حد اکثر زمان خواندن از ReceiveTimeout استفاده کنید.
قبل از آشنایی با بحث ارسال و دریافت اطلاعات در شبکه ابتدا باید با ساخت یک برنامه سرور آشنا بشیم.
کلاس TcpListener
از این کلاس برای ساخت یک شنودگر پورت استفاده می شود تا به درخواست ها پاسخ بدهد. در واقع وظیفه ارسال و دریافت اطلاعات به صورت ارتباط اتصال گرا بر عهده TcpClient می باشد. با استفاده از کلاس TcpListener میتوانیم به برای هر درخواست کلاینت یک TcpClient به دست بیاوریم که در واقع کانال ارتباطی سرور و کلاینت را تشکیل می دهد. همچنین در موارد خاص می توانیم یک نمونه از کلاس Socket را به دست بیارویم.
بسیار خب برای اینکه روی یک پورت شروع به شنود کنیم باید یک نمونه از این کلاس را با استفاده از این سازنده بسازیم که در ورودی یک آدرس IP می پذیرد(برای شنود روی واسط محلی IPAddress.Any تنظیم شود) و در پارامتر دوم یک شماره پورت می پذیرد.
حال برای شروع عملیات شنود متد Start را فراخوانی کنید. همچنین میتوانید این بازنویسی از متد Start را فراخوانی کنید که به عنوان ورودی یک عدد می پذیرد که تعداد افرادی که میتوانند به سرور متصل شوند را نمایش می دهد.
بعد از شروع شنود برای قبول کردن اتصال های ورودی میتوانید از متد های AcceptTcpClient و AcceptSocket استفاده کنید.
این متد ها به ترتیب یک نمونه از TcpClient و Socket را بر می گردانند. این ها همان مسیر ارتباطی هستند که باید ذخیره شوند.
اگر فقط یک کلاینت قبول میکنید میتوانید آن را به صورت یک متغییر سراسری تعریف کنید. اگر سرور به چندین کلاینت قرار است پاسخ دهد میتوانید از یک لیست یا آرایه استفاده کنید.
همچنین در انتها میتوانید با استفاده از متد Stop به شنود خاتمه دهید.
نکته ای راجع به توابع AcceptTcpClient و AcceptSocket
بدی که توابع AcceptTcpClient و AcceptSocket دارند این است که باعث ایجاد وقفه در تردی میشوند که در آن قرار دارند. راه جلوگیری از وقفه استفاده از متد Pending است. این متد برسی میکند که آیا کسی میخواهد به سرور متصل شود یا خیر. اگر کسی در صف بود شما میتوانید یکی از این دو متد را فراخوانی کنید.
یک مثال از شنود کردن
کلاس NetworkStream
از این کلاس برای ارسال و دریافت اطلاعات در شبکه استفاده می شود. در واقع این کلاس یک انتزاع از ورودی و خروجی شبکه را به ما نشان می دهد و باعث می شود ما کمتر با جزئیات ارسال و دریافت اطلاعات در شبکه درگیر بشویم.
این کلاس ماننده یک Stream معمولی عمل میکند با یک سری از تفاوت ها که در اینجا به آنها می پردازیم
هنگامی که اطلاعاتی را میخوانید، برنامه ممکن است به حالت وقفه برود و تا زمان مشخصی که برایش تعیین کردید (ReceiveTimeout) منتظر دریافت اطلاعات بماند.
یا زمانی که اطلاعاتی را در شبکه مینویسید (با استفاده از متد Write) بعد از اتمام کار ممکن است قسمتی از اطلاعات ارسال نشوند و کار این تابع به پایان برسد.اما چرا؟ هنگامی که شما اطلاعاتی را ارسال میکنید اگر گیرنده مشغول پردازش اطلاعات قبلی باشد، فرستنده اطلاعات ارسال نشده را در یک بافر ذخیره میکند تا بعدا مجددا ارسال کند.
نحوه ارسال اطلاعات در شبکه
خب دوستان تا الا که با قسمت کوچکی از برنامه نویسی شبکه در C# آشنا شدید. الا بیاید یک نگاه کوتاهی به نحوه ارسال و دریافت اطلاعات در شبکه داشته باشیم.
وقتی ما میخوایم یک داده ای رو در شبکه انتقال بدیم باید اول بدونیم روی چه پروتکلی قراره این کارو انجام بدیم. انتخاب پروتکل خودش بستگی به برنامه ای داره که ما میخوایم بسازیم. برای مثال وقتی ما قصد داریم یک برنامه پخش زنده بسازیم بهتره که از داده گرام (UDP) استفاده کنیم.
اما اگر برنامه ما یک برنامه ارتباطی ماننده چت روم است بهتر است از ارتباط اتصال گرا استفاده کنیم(TCP).
بعد از انتخاب پروتکل ارسال در لایه های پایین باید نحوه فرمت بندی اطلاعات را مشخص کنیم. برای مثال آیا اطلاعاتی که ما قصد ارسال آن را داریم اندازه ثابتی دارند یا خیر، رشته ای است یا باینری و…
همه اینها باید تعیین شوند و توسط فرستنده و گیرنده پذیرفته شود.
برای نوشتن داده به صورت باینری میتوانید از BinaryWriter و BufferedStream به صورت زیر استفاده کنید :
همچنین برای دریافت اطلاعات میتوانید از روش زیر استفاده کنید :
برای ارسال رشته هم کافیه اول رشته رو با استفاده از کلاس Encoding تبدیل به یک آرایه از بایت کنید و ابتدا اندازه رشته رو ارسال کنید(به روش ارسال بالا) و بعد خود رشته رو به صورت یک آرایه از بایت ها.
خب دوستان خیلی ممنونم که تا اینجا با من همراه بودید، امیدوارم موفق باشید
دیدگاهتان را بنویسید
برای نوشتن دیدگاه باید وارد بشوید.