ایران سرفراز- نرم افزار وپروژهای دانشجویی


نرم افزار وپروژهای دانشجویی

فصل بیست و ششم برنامه نویسی شبکه درTCP,UDP کاربرد پروتکل های#C

<!-- /* Font Definitions */ @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman","serif"; mso-fareast-font-family:"Times New Roman";} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; font-size:10.0pt; mso-ansi-font-size:10.0pt; mso-bidi-font-size:10.0pt;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:35.4pt; mso-footer-margin:35.4pt; mso-paper-source:0; mso-gutter-direction:rtl;} div.Section1 {page:Section1;} -->

فصل بیست و ششم

برنامه نویسی شبکه

 C#درTCP,UDP کاربرد پروتکل های

آنچه که در این فصل عنوان م یگردد:

مقدمه ای بر شبکه بندی و سوک تها

TCP • مثال پردازش و انتقال فرمان با

UDP • مثال پردازش و انتقال فرمان با

UDP به وسیله چندپخشی NewsTicker • ایجاد یک

-1-26 مقدمه

می توان شبکه بندی را به عنوان ارتباط داخل پرداز ش 1 تعریف کر د . دو یا چند پردازش با همدیگر ارتباط برقرار م ی کنند .

پردازش ها روی کامپیوترهای یکسان یا مختلف یا روی دستگا ه های فیزیکی دیگر اجرا م ی گردند. اتصال مابین گر ه های شبکه

cell Phone- WireLess ) و اینترنت ) یا بوسیله فرکانس های رادیویی ب یسیم LAN- WAN) اکثرا" بوسیله یک سیم

برقرار می گردد. (infrared) یا بوسیله نور ماورای بنفش (LAN- Bluetooth

را م ی پوشانیم. با مروری بر تاریخچه شبک ه بندی و #C در این فصل مفاهیم پای ه ای شبکه بندی و نحو ه ی بنا کر د ن آن در

را بررسی م ی کنیم . همچنین روی پور ت ها و TCP,UDP اینترنت و سوک ت ها شروع م ی کنیم. سپس پروتکل های معمول

را شرح می دهیم. NET. کاربردهای آنها نگاهی می اندازیم. در نهایت کلا س های موجود

1 Inter process communication

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

480

داشتن یک روش استان د ارد برای ارتباط انواع مختلف شبک هها و انواع مختلف کامپیوترها ضروری اس ت . بنابراین پروتکل

یک خانواده پروتکل است که ارتباط TCP/IP . توسعه داده شده و یک استاندارد جهانی ش د ARPA بوسیله TCP/IP

فقط دو پروتکل از این خانواده IP و TCP) کامپیوترهای متصل به هم و اشترک منابع ما بین یک شبکه را مجاز م ی دارد

مراجعه کنید. Sytem.Net.Sockets.Socket به مستندات کلاس NET. هستند). برای دسترسی به همه پروتکل های

از طریق یک برنامه به سوک ت ها نیاز داری م . سوکت یک واسط برنام ه نویسی و نقطه IP برای دستیابی به شبک ه های مبنی بر

انتهایی ارتباط است که م ی تواند برای اتصال به کامپیوترهای دیگر، ارسال و دریافت داده به آنها استفاده شو د . سوکت ها در

1 معماری - خوانده شدند. شکل 26 Berkeley Sockets سیستم عامل یونیکس برکلی عنوان شدند. به همین دلیل آنها

را نشان می دهد. TCP/IP کلی ارتباط مبتنی بر

1- شکل 26

در کل سه نوع سوکت وجود دارد:

مثالی از سوکت های خام است. IP . - سوکت های خام 1: این سوکت ها روی لایه شبکه ایجاد می شوند

- سوکت های داده گرام 2: داده گرام ها بسته هایی از داده هستن د . این نوع سوک ت ها روی لایه انتقال پیاد ه سازی می شوند

مبتنی بر IP ، 2 را ببینی د ). با این و ج ود، فقط به یک لایه انتساب داده شده است، چون به عنوان مثال - ( شکل 26

داده گرام است.

- سوکت های جریان 3: برخلاف سوکت های داده گرام، این سوک تها یک جریان داده فراهم می کنند.

در ادامه فصل، سوک تهای داده گرام و جریان بصورت دقیق بررسی خواهند شد.

2- شکل 26

1 Raw

2 Datagram

3 Stream

فصل بیست و ششم برنامه نویسی شبکه

481

معماری های ارتباط مدرن، یک پشته از پروتک ل های مختلف لای ه ها را بکار م ی برند، که داد ه ها را به لایه بالایی تحویل

می دهند. هر لایه اطلاعات مرتبط به لای ه ی خود را به داد ه ها اضافه م ی کند و سپس به لایه بعدی تحویل م ی دهد . داده ها

توسط پایین ترین لایه به کامپیوتر ط ر ف مقابل تحویل داده می شوند. در طرف مقابل هر لایه برعکس لایه متناظر خود در

2 یک پشته پروتکل نشان می دهد. - ارسال کننده عمل می کند. شکل 26

TCP -1-1 مقدمه ای بر -26

شبیه تلفن اس ت . ممکن است بخواهید با ع موی خود TCP یک ارتباط اتصا ل گرا یا جریا ن گرا و مطمئن اس ت . ارتباط TCP

3 نمایش داده م ی شود . اگر - صحبت کنید . بوسیله شماره گیری یک اتصال ( نقطه به نقطه ) برقرار می کنیم. در شکل 26

4). شرکت مخابرات تضمین م ی کند صدای شما - عموی شما در خانه باشد، گوشی را برداشته با شما صحبت م ی کند( شکل 26

را عینا " به سمت مقابل ارسال کن د ( قابلیت اطمینان ). تا زمانی که ارتباط برقرار است، شما بطور پیوسته صحبت م ی کنید (

جریان گرا).

3- شکل 26

4- شکل 26

5 را برای مثال قطع اتصال مشاهده کنید. - این اتصال تا زمان پایان مکالمه شما ادامه دارد ( اتصال گرا). شکل 26

5- شکل 26

است. همانطور که Best-effort داده گرام-گرا و پروتکل IP . را به عنوان پروتکل شبکه خود بکار می برد IP پروتکل TCP

به این معنی است که داده گرام ها بدون Best-effort . قبلا" شرح داده شده، داده گرام ها بسته هایی از داده هستند

تضمین تحویل و صحت ترتیب ارسال می شوند.

جریان یافتن داده را شبی ه سازی کند . بنابراین لازم است ترتیب و صحت TCP جریان گرا اس ت. باید TCP ، همانطور که دیدید

داده گرام ها را کنترل کن د . اگر داد ه گرام ها را کنترل کند، در صورت خراب شدن یا گم شدن، باید آن را مجدد ا" ارسال کن د .

تعدادی زما ن سنج پروتکل برای تضمین ارتباط همگام شده TCP . اگر این کار انجام نشود، یک خطا گزارش م ی شود

پیاده سازی می کند. در صورت نیاز، می توانیم از این زما نسنج ها در تولید اتمام مهلت زمانی 1 استفاده کرد .

1 Timeout

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

482

است . این Http, Ftp, Telnet پایه پروتکل های قابل اطمینان همچون TCP . به قابلییت اطمینان آن است TCP مزیت

پروتکل ها در صور ت ی لازم هستند که تحویل و ترتیب بست ه ها مهم باش د . برای مثال، اگر یک پست الکترونیکی به عموی خود

کاهش Tcp تحویل داده نمی شود . عیب 'Hlnt Aelvo' ارسال کنید. آن به صورت "Hello Aunt" با عبارت آغازی

را نشان http 6 یک پش ت ه از لای ه های ارتباط بوسیله - کارایی آن به دلیل سربار مدیریت قابلیت اطمینان اس ت . شکل 26

می دهد.

6- شکل 26

را انتخاب کنیم. این پروتکل در بخش بعدی بحث م یشود. UDP اگر قابلیت اطمینان لازم نباشد، می توانیم پروتکل

UDP -2-1 مقدمه ای بر -26

شبیه ارسال یک نامه اس ت . ممکن UDP داده گرام-گرا است . ارتباط Best-effort یک پروتکل بی اتصال و پروتکل UDP

است بخواهید یک نامه به عموی خود ارسال کنید و نم ی خواهید نامه را به صورت دستی به عموی خود تحویل دهی د . اداره

7 را ببینید ). ارسال یک نامه اکثر اوقات - پست، نامه را از شما تحویل گرفته و یکجا به عموی شما تحویل م ی دهد( شکل 26

پیشنهاد م ی کند. آنها ترتیب ارسال نامه را تضمین Best-effort نه ه میشه، قابل اطمینان اس ت . اداره پست، یک سرویس

نمی کنند. اگر شما نامه 1 را امروز و نامه 2 را فردا ارسال کنید، عموی شما ممکن است نامه شماره 2 را قبل از نامه 1 دریافت

8 را ببینید). - کند(شکل 26

- از طرف دی گ ر، ممکن است یکی از نام ه ها گم شو د . اداره پست تضمین نم ی کند یک نامه حتم ا " تحویل خواهد ش د (شکل 26

9 را ببینید).

7- شکل 26

8- شکل 26

فصل بیست و ششم برنامه نویسی شبکه

483

9- شکل 26

پس چرا این پروتکل استفاده می شود. به دلایل زیر:

است . چون هیچ بررسی سربار روی بست ه ها ن د ارد. بنابراین از آن در برنام ه های TCP سریع تر از UDP : - کارایی

کاربردی زمان بحرانی همچون جریان ویدیو و جریان صدا استفاده م یکنند.

- اگر برنامه شما در مورد گم شدن بست ه ها دقت نم ی کند. به عنوان مثال، یک سرور زمان را در نظر بگیری د . اگر سرور

یک بسته ارسال کند و آن بسته گم شود، آن اسرار نم ی کند که زمان را باید مجدد ا" ارسال کن د . اگر سرویس

گیرنده در تلاش بعدی آن را دریافت کند، بسته نادرست است.

TCP بایت برای اطلاعات سرایند پروتکل نیاز دارد. در حالیکه UDP ترافیک کمتری در شبکه ایجاد می کند. 8 UDP -

حداقل 20 بایت نیازدار د . زمانی که صحبت از هاردهای گ ی گا بایتی است، 16 بایت یک مشکل به حساب نم ی آید، اما

مجموع همه بسته های ارسالی در ارتباطات جهانی را تصور کنید که 16 بایت رقم بالایی ایجاد خواهد کرد.

برای آزمایش ping برای تحلیل شبکه نیاز دار د . برای نمونه دستور Best–effort - اگر برنامه ی شما یک پروتکل

ارتباط ما بین دو کامپیوتر یا پردازش استفاده م ی شود. این دستور میزان بست ه های خراب شده یا گم شده را

Ping می خواهد تا کیفیت اتصال را تعیین کن د . پس لازم نیست یک پروتکل قابل اطمینان برای برنام ه هایی همچون

استفاده شود.

تلفن اینترنتی یا جریان یافتن اطلاعات چند رسانه ای استفاده م یشود . مزیت دیگر ، SNMP ,DNS برای UDP " عموما

10- خاص در یک گروه قرار م ی گیرند(شکل 26 IP در چندپخشی آن اس ت . یعنی تعدادی از پرداز ش ها بوسیله یک UDP

باید در محدوده 224,0,0,1 تا 239,255,255,255 باشد . هر پروسه موجود در گروه م ی تواند IP را ببینید ). آدرس

بسته ای را به همه پروس ههای دیگر گروه ارسال کند.

10- شکل 26

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

484

هیچ پروسه ای در مورد تعداد پروس ه های موجود در گروه اطلاعی ندار د . اگر یک برنامه کاربردی بخواهد داد ه ای به

گروه ارسال کن د . روی پروتکل لایه هیچ پروس ه ای سرور نیست. کار شما IP دیگری ارسال کند، باید داده را به آدرس

تعریف سرورها و سرویس گیرنده ها است.

بخش بعدی پور تها را توضیح می دهد. پورت ها برای تعیین برنامه های درحال اجرای روی یک کامپیوتر مهم هستند.

-3-1 مقدمه ای بر پورت ها -26

در کل هر کامپیوتری فقط یک اتصال واحد به شبکه دار د . اگر همه داده ها از طریق ی ک اتصال برسند، چگونه مشخص

می شود آن داد ه ها توسط کدام برنام ه ی در حال اجرا دریافت م ی شود؟ جواب همان پور ت ها هستند . پورت یک عدد 16 بیتی

و )MAIL25( ،HTTP( در محدوده 0 تا 65535 است . شماره های پورت 0 تا 1023 برای سروی س های خاص همچون ( 80

رزرو شد هاند. Telnet(23)

یک برنامه متصل باید حداقل به یک پورت مقید شو د . مقید کردن بدین معنی است که یک پورت به سوکت مورد استفاد ه ی

برنامه کاربردی اختصاص داده م ی شود. برنامه کاربردی در سیست م عامل ثبت م ی شود. همه بسته های ورودی که در سرآیند

11 را ببینید). - آنها شماره پورت برنامه مورد نظر قرار دارد، به این برنامه تحویل داده می شود(شکل 26

11- شکل 26

11 به معنای مقید کردن فقط یک سوکت به یک پورت نیس ت . اگر یک سوکت از طریق یک پورت - توجه کنید که شکل 26

برای یک اتصال ورودی منتظر بماند، بطور عادی پورت برای برنام ه های دیگری بلوکه م ی شود. انتظار سوکت برای یک اتصال

در سمت سرور اس ت . اگر یک اتصال بوسیله سوکت سرور پذیرفته شود، آن یک سوکت جدید برای نمایش این اتصال ایجاد

می کند. سپس سوکت سرور م ی تواند برای یک تقاضای اتصال جدید منتظر بمان د . پس چندین سرویس گیرنده م ی توانند از

طریق یک پورت بطور همزمان ارتباط برقرار کنند.

است . در حالیکه یک صفحه وب درخواست شده از یک سرور بارگذاری م ی شود، WEB یک مثال برای این کار در سرور

را بیان م ی کند که ما Net می توانید صفحه دیگری از آن سرور را با کاوشگر دیگر بارگذاری کنی د . بخش بعدی کلا س های مهم

در مثا لهای خود از آنها استفاده می کنیم.

فصل بیست و ششم برنامه نویسی شبکه

485

System.Net -4-1 فضای نامی -26

کلا س های پایه برای عملکرد شبکه را دربردار د . فضای نامی System.Net.Sockets در حالیکه فضای نامی

کلاس هایی دارد که کلا س های پایه شبکه را کپسوله کرده و دستیابی به آنها را راح ت تر م ی سازند. کلاس های System.Net

یک واسط برنامه نویسی ساده برای بعضی از پروتک لهای مورد استفاده شبکه دارند. System.Net

هستند . این کلا س های انتزاعی پایه پیاد ه سازی WebResponse و WebRequest در مرکز این فضای نامی کلا س های

به همراه ) HttpWebRequest با کلاس HTTP : پروتکل ها هستند. دو پروتکل از پیش تعریف شده اند

.(FileWebResponse به همراه ) FileWebRequest بوسیله کلاس //:file و پروتکل (HttpWebResponse

کلا س های تصدیق و جواز، استثنا ء ها و گواه ی ها وجود دارن د . کلاس هایی که ،IP کلاس های کمکی دیگری همچون آدر س های

1 نشان داده می شود. - در این فصل استفاده می کنیم در جدول 26

1- جدول 5

کلاس توصیف

را نشان م یدهد. IP یک آدرس IPAddress

یک نقطه انتهایی شبکه را تعیین م ی کند . نقطه انتهایی در شبکه IPEndPoint

و یک پورت است. IP شامل یک

System.Net.Sockets -5-1 فضای نامی -26

همانطور که قب لا " شرح داده شده، این فضای نامی کلا س های پایه برای فراهم کردن عملیات شبکه را در بر دار د . کلاس

است . همانطور که م ی دانید سوکت اساس ی ترین واسط برنام ه نویسی شبکه اس ت . ما بیشتر کلا س های این Socket مرکزی آن

2 این کلا سها را نشان می دهد. - فضای نامی را بکار می بریم. جدول 26

2- جدول 26

کلاس توصیف

واسط برنامه نویسی سوک تهای برکلی را پیاد هسازی می کند Socket

دسترسی آسان به داده های سوک تهای جریان را مجاز م یدارد. NetworkStream

برای وصل به یک سوکت سرور فراهم می کند. TCP یک سرویس گیرنده TcpClient

سرور برای گوش دادن به تقاضاها ی اتصال ورودی پیاد ه سازی TCP یک سوکت TcpListener

می کند.

با امکان چندپخشی فراهم می کند. UDP یک سرویس گیرنده UdpClient

و غیره را نشان م یدهیم. TCP بحث تئوری کافی است. در بخش بعدی با مثا لهای عملی کاربرد

TCP -2-26 مثال انتقال و پردازش دستورات در

این مثال یک جدا سازی صریح مابین لا یه نمایش و لایه عملیات اس ت . لایه نمایش واسط کاربر است، چون باید شما ابتدا روی

ارتباط تمرکز کنی د . این مثال یک برنامه کنسولی بکار م ی برد و بعدا م ی توانید به ایجاد یک واسط کاربری خوب بپردازی د . لایه

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

486

عملیاتی بخشی از برنامه کاربردی است که همه کار را انجام م ی دهد ( برای مثال، یک شی تجاری برای محاسبه بعضی

12 یک معماری ساده از اولین مثال را نشان م یدهد - چیزها). شکل 26

12- شکل 26

برای لایه ی نمایش محل اجرای عملیات مهم نیس ت . می توانید لایه عملیات را در همان برنامه کاربردی، در پروسه دیگر روی

یا اینترنت پیاده سازی کنید. برای انعطا فپذیر کردن این معماری، یک LAN همان کامپیوتر یا روی یک ک امپیوتر دیگر در

پردازشگر دستور ما بین لایه نمایش و لایه عملیاتی اضافه خواهید کر د . پردازشگر دستور یک واسط استاندارد برای لایه

عملیاتی است . لایه ی نمایش، تقاضاها را به صورت دستوراتی به پرد ازنده می دهد. پردازنده متدهای لایه عملیاتی را بر اساس

13 معماری - دستورات اجرا م ی کند. در نهایت، پردازشگر دستور، نتایج را گرفته و آن را به لایه نمایش بر م ی گرداند. شکل 26

توسعه یافته را نشان م یدهد.

پردازشگر دستور دسترسی به لایه عملیاتی را با رو ش های مختلفی س اده می سازد ( از طریق همان برنامه کاربردی یا ارتباط

14 یک مثال با یک لایه عملیاتی دور را نشان م ی دهد. مزیت این مدل در این است که - شبکه ای به کامپیوتر دیگ ر ). شکل 26

لایه نمایشی نم ی داند لایه عملیاتی کجا اجرا م ی گردد. آن فقط دستورات را به پردازشگر دستور داده و نتیجه را دریافت

می کند.

تایپ URL یک مثال معمول از این نوع معماری، ارتباط کاوشگر وب با سرور وب اس ت . شما در فیلد آدرس کاوشگر خود یک

از سرور وب تبدیل کرده و تقاضا را به آن ارسال م ی کند . سرور وب GET را به یک تقاضای URL می کنید. کاوشگر این

به کاوشگر بر می گرداند. HTML درخواست شما را تحلیل می کند و یک صفحه

13- شکل 26

14- شکل 26

فصل بیست و ششم برنامه نویسی شبکه

487

این مثال همان کار را بصورت بسیار ساده انجام م ی دهد. یک سرویس گیرنده کنسولی، یک تقاضا به سرور ارسال م ی کند و

را به سرویس گیرنده بر می گرداند. این مثال یک پروتکل ارتباطی ساده را با دو دستور "Hello World" سرور عبارت

پیاده سازی می کند. نمونه ای از ارتباط بصورت زیر است: GET, EXIT

c: (establish tcp connection to the server)

s: (accept connection)

c: GET<CRLF>

s: "Hello World !"<CRLF>

c: EXIT<CRLF>

s: BYE<CRLF>

c: (close connection)

s: (close connection)

است. معمولا این روش ENTER علامت کلید <CRLF> . همان سرویس دهنده را مشخص می کند S همان سرویس گیرنده و C

استفاده می شود. SMTP یا HTTP بوسیله پروتکل های ارتباطی همچون

.Net -1-2 کاربرد کلاس های معمول -26

و System.Net.Sockets.TcpClient دو کلاس اصلی شبکه را برای این مثال نیاز دار ی د. در سمت سرویس گیرنده

به TcpClient در کل در طرف سرویس گیرنده یک .System.Net.Sockets.TcpListener درسمت سرویس دهنده

سرویس دهنده متصل م ی گردد. سپس با کمک یک جریان داده، بوسیله سرویس گیرنده روی اتصال کار م ی کنید. بعد از اتمام

کار سرویس گیرنده را می بندد.

// connect client to the server 127.0.0.1:8080

TcpClient client = new TcpClient ( "127.0.0.1", 8080 );

// get the network stream for reading and writing something

// to the network

NetworkStream ns = client.GetStream ();

// read/write something from/to the stream

// disconnect from server

client.Close ();

را روی یک پورت TcpListener طرف سرویس دهنده یک مرحله بیشتر دار د . اما در کل کد آنها شبیه هم اس ت . یک

محلی مقید کنی د . حال اگر یک سرویس گیرنده به گوش کننده وصل شود، یک سوکت بدست م ی آید و بوسیله این

سوکت، یک جریان ایجاد می کند. از این نقطه کد شبیه طرف سرویس گیرنده است.

// create a listener for incoming TCP connections on port 8080

TcpListener listener = new TcpListener ( 8080 );

listener.Start ();

// wait for and accept an incoming connection

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

488

Socket server = listener.AcceptSocket ();

// create a network stream for easier use

NetworkStream ns = new NetworkStream ( server );

// read/write something from/to the stream

// disconnect from client

server.Close ();

بعد از یک نگاه به کاربرد کلی کلاس های شبکه بندی، اولین مثال خود را بررسی م یکنیم.

-2-2 سرویس دهنده -26

است. برای سادگی سرویس گیرنده فقط یک TcpHelloWorldServer با سرویس دهنده شروع می کنیم. کلاس آن بنام

پردازشگر دستور دار د . بعدا" مثال هایی نشان م ی دهیم که سرویس دهنده نیز یک پردازشگر دس ت ور دارد . برای سرویس

را دارد. ( )Main 18 ) فضاهای نامی زیر را لازم دارید. کلاس فقط متد - 15 تا 26 - دهنده (قطعه کدهای 26

15- قطعه کد 26

using System;

using System.IO;

using System.Net.Sockets;

است . آن مقد اردهی اولیه سرویس دهنده را نشان TCPHelloWorldServer در ()Main 15 یک قطعه از مت د - قطعه کد 26

را بکار برید. TcpListener می دهد. برای اینکه روی پورت 8080 منتظر اتصالات ورودی باشد، یک نمونه از

16- قطعه کد 26

Console.WriteLine ( "initializing server..." );

TcpListener listener = new TcpListener ( 8080 );

listener.Start ();

Console.WriteLine ( "server initialized, waiting for " +

"incoming connections..." );

Socket s = listener.AcceptSocket ();

// create a NetworkStream for easier access

NetworkStream ns = new NetworkStream ( s );

// use a stream reader because of ReadLine() method

StreamReader r = new StreamReader ( ns );

یک سوکت برای نمایش اتصال سرویس AcceptSocket گوش کننده ی پورت 8080 به اتصالات ورودی گوش م ی دهد. متد

دهنده بر می گرداند. این متد برنامه را بلوک می کند، تا زمانیکه یک سرویس گیرنده با گوش کننده اتصالی باز کند.

برای انتقال داده بوسیله سرویس گیرنده ،AcceptSocket بعد از اینکه یک اتصال برپا ش د . سوکت برگردانده شده توسط

است . این کلاس در فضای نا می NetworkStream متصل استفاده م ی شود. راحت ترین روش انجام این کار، استفاده از یک

قرار گرفته، که متدهای خواندن و نوشتن در شبکه را کپسوله م یکند. پس System.Net.Sockets .NetworkStream

اس ت . این کلاس StreamReader می توانید این کلاس را فقط برای کار روی جریا ن ها بکار بری د . مرحله بعدی ایجاد یک

است . این کلاس دسترسی به یک جریان را ساده م ی کند . در اینجا به خ ا طر متد System.IO بخشی از فضای نامی

از این کلاس استفاده م ی شود. این متد یک خط واحد از کاراکترها را م ی خواند. مجموعه ای از کاراکترها که در ()ReadLine

قرارمی گیرد، را خط گویند. n\r\ انتهای آنها

بعد از اینکه سرویس گیرنده یک اتصال برپا م ی کند. آن یک دستور به سرویس دهند ه ی متصل ارسال م ی کند. حال، دستور

17 نمایش داده می شود. - ورودی توسط سرویس دهنده تحلیل شده و اجرا م یشود که آن در قطعه کد 26

17- قطعه کد 26

bool loop = true;

while ( loop )

{

// read a line until CRLF

string command = r.ReadLine ();

string result;

Console.WriteLine ( "executing remote command: " +

command );

switch ( command )

{

case "GET":

فصل بیست و ششم برنامه نویسی شبکه

489

result = "Hello World !";

break;

// finish communication

case "EXIT":

result = "BYE";

loop = false;

break;

// invalid command

default:

result = "ERROR";

break;

}

if ( result != null )

{

Console.WriteLine ( "sending result: " + result );

// add a CRLF to the result

result += "\r\n";

// convert data string to byte array

Byte[] res = System.Text.Encoding.ASCII.GetBytes (

result.ToCharArray () );

// send result to the client

s.Send ( res, res.Length, 0 );

}

}

برمی گرداند و حلقه ادامه پیدا م یکند . در صورتی "Hello World" دریافت شود، سرویس دهنده رشته GET اگر دستور

،EXIT برگردانده م ی شود. با دستور "ERROR" که دستور مجهولی برسد، دوباره حلقه ادامه پیدا م ی کند. در این حالت، رشته

18 را ببینی د ). برای بستن اتصال - سرویس دهنده حلقه را متوقف م ی کند. بعد از این کار، باید اتصال بسته شو د (قطعه کد 26

منتظر می ماند. Enter را فراخوانی کنید. در نهایت، سرویس دهنده برای فشار دادن کلید Socket کلاس ()Close متد

18- قطعه کد 26

Console.WriteLine ( "clearing up server..." );

s.Close ();

Console.Write ( "press return to exit" );

Console.ReadLine ();

تمام این کد برای سرویس دهنده بود، حال سرویس گیرنده را بررسی م یکنیم.

-3-2 سرویس گیرنده -26

و پ ر دازشگر دستور UI)) سرویس گیرنده کمی پیچید ه تر از سرویس دهنده اس ت . آن دو بخش دار د : برنامه کاربردی کنسولی

که قطعات ارتباط را در بر دارد.

25 در فایل - 19 تا 26 - را بررسی م ی کنیم. قطعه کدهای 26 TcpRemoteCommandProcessor ابتدا پردازشگر دستور بنام

تولید خواهد کر د . فضاهای نامی مورد استفاد ه ی پردازشگر Base.dll یک کتابخانه بنام Base.cs هستند که Base.cs

19 نمایش داده می شود. - دستور در قطعه 26

19- قطعه کد 26

using System;

using System.IO;

using System.Net.Sockets;

ابتدا یک واسط خواهیم نوش ت . پیاده سازی بیش از یک پردازشگر دستور با پروتک ل های اصلی شبکه توسط این واسط

امکان پذیر است . پس سرویس گیرنده نمون ه ای از این و اسط را بکار م ی برد. این واسط سرویس گیرنده را از پروتکل مورد

20 را ببینید). - استفاده شبکه مستقل می سازد( قطعه کد 26

20- قطعه کد 26

public interface CommandProcessor

{

// execute a command and return the result

// if the return value is false the command processing loop

// should stop

bool Execute ( string command, ref string result );

}

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

490

را برای پیاد ه سازی واسط پردازشگر دستور ایجاد کنی د . این کلاس سه متد TcpRemoteCommandProcessor حال کلاس

پردازشگر دستو ر در دو مد مختلف اجرا م ی گردد . در .()Execute و پیاد ه سازی متد ()Close دارد: یک سازنده، یک متد

سازنده در داخل خود اتصال به سرویس دهنده را مستقیم ا " برقرار م ی کند. قطع اتصال در زمان فراخوانی ،Hold مد اتصال

صورت می گیرد. ()Close متد

در صورت درخواست ارسال یک دستور به سرویس دهنده از طرف پردازشگر، ات ص ال برقرار م ی گردد. Release در مد اتصال

بعد از بازیابی نتیجه، اتصال بسته م ی شود. مد اول برای ارتباط کوتاه یا بهر ه وری بالا اس ت . مد دوم برای ارتباط طولانی است و

می تواند برای صرف هجویی پول روی اینترنت یا کاهش استفاده از منابع شبکه بکار برده شود.

21 همه اطلاعات و اشیاء مورد نیاز جهت اجرای پروسه ارتباط را نشان - با فیلدهای کلاس شروع م ی کنیم. قطعه کد 26

می دهد.

21- قطعه کد 26

// remote host

private string host = null;

// remote port

private int port = -1;

// connection mode

private bool releaseConnection = false;

// communication interface

private TcpClient client = null;

// outgoing data stream

private NetworkStream outStream = null;

// ingoing data stream

private StreamReader inStream = null;

22 ببینید . آن سه پارامتر دار د : نام و شماره پورت میزبان و یک پرچم بولین برای - حال سازنده کلاس را در قطعه کد 26

کار می کند، در غیر اینصورت، مد اتصال Release باشد، پردازشگر دستور در مد اتصال True تعیین مد اتصا ل . اگر پرچم

استفاده شود، سازنده به وسیله نام و شماره پورت میزبان فور ا" به Hold فعال اس ت . اگر پردازشگر دستور در مد Hold

سرویس دهنده وصل م یگردد. نهایتا" فیلدهای جریان ورودی و جریان خروجی را مقداردهی اولیه م یکند.

22- قطعه کد 26

public TCPRemoteCommandProcessor ( string host, int port,

bool releaseConnection )

{

// add parameter checking here

this.host = host;

this.port = port;

this.releaseConnection = releaseConnection;

if ( !this.releaseConnection )

{

Console.WriteLine ( "connecting to " + this.host + ":" +

this.port + "..." );

this.client = new TcpClient ( this.host, this.port );

this.outStream = this.client.GetStream ();

this.inStream = new StreamReader ( this.outStream );

Console.WriteLine ( "connected to " + this.host + ":" +

this.port );

}

}

Release 23 را ببینی د ). این فقط در مد اتصال - کاملا " ساده اس ت . آن فقط اتصال را م ی بندد( قطعه کد 26 ()Close متد

null باشد، این متد هیچ کاری انجام نم ی دهد و همه فیلدها را Hold انجام خواهد ش د . اگر پردازشگر فرمان در مد اتص ا ل

قرار می دهد.

23- قطعه کد 26

public void Close ()

{

if ( this.client != null )

{

this.client.Close ();

Console.WriteLine ( "connection closed: " + this.host +

":" + this.port );

فصل بیست و ششم برنامه نویسی شبکه

491

}

}

باشد، آن باید ابتدا به سرویس دهنده وصل Release پیچیده تر است . اگر پردازشگر دستور در مد اتصال ()Execute متد

24 را ببینی د ). در هنگام ارسال در انتهای دستور کاراکترهای کلید - گردد و بعد از ارسال دستور آن را ببند د (قطعه کد 26

الحاق م ی شوند و سپس به یک آرایه بایتی تبد ی ل می شوند. این آرایه به جریان خروجی داده م ی شود . پردازشگر Enter

در غیر True است؟ اگر باشد "BYE" دستور جواب را از جریان ورودی م ی خواند و در نهایت بررسی م ی کند، آیا جواب رشته

برمی گرداند. False این صورت

24- قطعه کد 26

public bool Execute ( string command, ref string result )

{

// add parameter checking here

bool ret = true;

if ( this.releaseConnection )

{

Console.WriteLine ( "connecting to " + this.host + ":" +

this.port + "..." );

// open connection to the server

this.client = new TcpClient ( this.host, this.port );

this.outStream = this.client.GetStream ();

this.inStream = new StreamReader ( this.outStream );

Console.WriteLine ( "connected to " + this.host + ":" +

this.port );

}

// add a CRLF to command to indicate end

command += "\r\n";

// convert command string to byte array

Byte[] cmd = System.Text.Encoding.ASCII.GetBytes (

command.ToCharArray () );

// send request

this.outStream.Write ( cmd, 0, cmd.Length );

// get response

result = this.inStream.ReadLine ();

if ( this.releaseConnection )

{

// close connection

this.client.Close ();

Console.WriteLine ( "connection closed: " + host + ":"

+ port );

}

ret = !result.Equals ( "BYE" );

return ret;

}

بنامی د . TcpHelloWorldClient در پایان کار، شما یک سرویس گیرنده برای استفاده پردازشگر فرمان نیاز داری د . آن را

قرار خواهد گرف ت . آن برای ارتباط با سرویس دهنده یک TcpHelloWorldClient کد منبع این س رویس گیرنده در فایل

را ارسال م ی کند و نتیجه را روی کنسول نمایش GET ایجاد م ی کند. سپس دستور TcpCommandProcessor نمونه از

را ارسال م یکند و اتصال را می بندد. EXIT می دهد. سرانجام دستور

25- قطعه کد 26

using System;

using System.IO;

using System.Net.Sockets;

public class TCPHelloWorldClient

{

public static void Main ()

{

Console.WriteLine ( "initializing client..." );

TCPRemoteCommandProcessor proc = new

TCPRemoteCommandProcessor ( "127.0.0.1", 8080, false );

string result;

Console.WriteLine ( "requesting..." );

proc.Execute ( "GET", ref result );

Console.WriteLine ( "result: " + result );

Console.WriteLine ( "closing connection..." );

proc.Execute ( "EXIT", ref result );

proc.Close ();

Console.Write ( "press return to exit" );

Console.ReadLine ();

}

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

492

}

حال می توانید مثال را کامپایل کرده و اجرا کنید.

-4-2 کامپایل کردن و اجرای برنامه -26

2005 ایجاد کرده و با اسامی مشخص شده ذخیره کنید و سپس آنها را کامپایل کنید تا فای ل ها ی Vs فایل های منبع آنها را در

سرویس دهنده را اجرا کنی د . یک پنجره کنسول ،TcpHelloWorldServer اجرایی تولید شو د . با دابل کلیک روی برنامه

26 ظاهر می گردد. - شبیه شکل 26

سرویس گیرنده را شروع کنی د . پنجره کنسول ،TcpHelloWorldClient.exe حال می توانید با دابل کلیک کردن روی

27 ظاهر خواهد شد. - دیگر شبیه شکل 26

26- شکل 26

27- شکل 26

28 می شود. حال می توانید با فشار دادن هر کلیدی برنام ه ها را متوقف کنی د . بخش بعدی همان - پنجره سرور شبیه شکل 26

ایجاد می کند. UDP مثال را بوسیله

28- شکل 26

UDP -3-26 مثال انتقال و پردازش دستور با

مجدد ا" می نویسید. مقدمه مربوط به معماری و پیاد ه سازی پروتکل ارتباطی UDP در این بخش مثال بخش ق ب لی را با پروتکل

را به خاطر بیاورید.

NET -1-3 کاربرد کلی کلا سهای ضروری -26

است. (P2P) فقط یک کلاس اصلی شبکه مورد نیاز اس ت . چون اداره کردن ارتباط نظیر به نظیر UDP در کاربرد TCP بر خلاف

را بکار م ی بریم. می توان گفت یک سرویس گیرنده System.Net.Sockets.UdpClient در هر دو طرف ارتباط، کلاس

به یک پورت محلی مقید م ی شود، تا داد ه ها را از آن دریافت کند. داده ها مستقیما" و بدون برقراری ارتباط صریح به UDP

دیگر ارسال م ی شوند و آن هم ا ن ارتباط بدون اتصال اس ت . در مجموع، کد هر دو طرف یکسان به نظر UDP سرویس گیرنده

به پورت محلی مقید م ی شود. حال برای ارسال و دریافت داده آماده هستن د . چون سرویس UdpClient می رسد. یک

فصل بیست و ششم برنامه نویسی شبکه

493

اطلاعات اتصال به میزبان دور لازم اس ت . این اطلاعات برای ()Send گیرنده فقط به یک پورت محلی مقید شده، پس در متد

را به پورت محلی مقید کردید، داد ه ها را از UdpClient طرف مقابل لازم هستن د . چون UDP ارسال داده به سرویس گیرنده

dummy محل دریافت خاصی را معین نم ی کنید. بدین دلیل است که متغیر ()Receive این پورت دریافت م ی کنید و برای متد

قرار دادیم. null مورد استفاده

// bind client to local port where it receives data

UdpClient client = new UdpClient ( 8081 );

// create a byte array containing the characters of

// the string "a request"

Byte[] request = System.Text.Encoding.ASCII.GetBytes (

"a request".ToCharArray () );

// send request to the server

client.Send ( request, request.Length, "127.0.0.1", 8080 );

// create a dummy endpoint

IPEndPoint dummy = null;

// receive something from the server

byte[] response = client.Receive ( ref dummy );

// do something with the response

// unbind the client

client.Close ();

آشنا شدید، حال مثال دوم را بررسی م یکنیم. NET. با کلا سهای شبکه در چارچوب

-2-3 سرور -26

دارد . مقداردهی اولیه سرور بسیار ساده است . فقط باید یک ()Main ابتدا سرور را بررسی م ی کنیم. کلاس فقط یک متد بنام

را نشان می دهد. ()Main 29 ابتدای متد - را به یک پورت محلی مقید کنید. قطعه کد 26 UdpClient

29- قطعه کد 26

Console.WriteLine ( "initializing server" );

UdpClient server = new UdpClient ( 8080 );

یک پروتکل بدون اتصال است. شما بدون دریافت یک تقاضا نم یتوانید پاسخی ارسال کنید. UDP چون

UDP می توانید بگویید که داد ه گرام ،IP اطلاعات سوکت ارسال کننده پیام را در بر دار د . در روی لایه UDP سرآیند داد ه گرام

نمی توانید به این اطلاعات #C فرستنده را در بر دارد، اما در IP آدرس IP تعبیه اس ت . سرآیند داده گرام IP در یک داد ه گرام

پس ساد ه ترین راه، اضافه کردن اطلاعات فرستنده به (NET. دسترسی داشته باشی د ( حداقل با نسخه بتای API از طریق

داده گرام است( اگر بخواهید گیرنده داده هایی را برگرداند). گرامر دستور ارسال به سرور بصورت زیر خواهد بود:

IP ADDRESS " : " PORT " : " COMMAND

دستور مورد نظر جهت اجرا است. کد سرور برای COMMAND و پورت فرستنده بوده و IP آدرس PORT و IP ADDRESS که

30 نشان داده شده اس ت . بعد از دریافت دستور آن را به بخ ش های مختلف تفکیک - دریافت یک دستور در قطعه کد 26

می کند.

30- قطعه کد 26

// an endpoint is not needed the data will be sent

// to the port where the server is bound to

IPEndPoint dummy = null;

bool loop = true;

while ( loop )

{

Console.WriteLine ( "waiting for request..." );

byte[] tmp = server.Receive ( ref dummy );

// split request string into parts, part1=client IP

// address or DNS name, part2=client port, part3=command

string dg =

new System.Text.ASCIIEncoding ().GetString (

datagram );

string[] cmd = dg.Split ( new Char[] {':'} );

string remoteClientHost = cmd[0];

int remoteClientPort = Int32.Parse ( cmd[1] );

string command = cmd[2];

string result = null;

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

494

// command execution

31- است . بنابراین کد ارسال نتیجه بصورت قطعه کد 26 TcpHelloWorldServer کد اجرای دستور همانند کلاس

می باشد.

31- قطعه کد 26

// convert data string to byte array

Byte[] d = System.Text.Encoding.ASCII.GetBytes (

result.ToCharArray () );

// send result to the client

server.Send ( d, d.Length, remoteClientHost,

remoteClientPort );

است. حال به بررسی سرویس گیرنده م یپردازیم. TcpHelloWorldServer کد متوقف کردن ارتباط شبیه کلاس

-3-3 سرویس گیرنده -26

اس ت . کد آن با UdpHelloWorldClient.CS است و نام فایل آن UdpHelloWorldClient سرویس گیرنده بنام

فقط یک اختلاف دار د (پردازشگر دستور و ایجاد یک نمونه از آ ن ). پردازشگر دستور بنام TcpHelloWorldClient

32 فقط خط متفاوت کد را نشان - ذخیره م ی شود. قطعه کد 26 BASE.CS بوده و در فایل UdpCommandProcessor

می دهد.

32- قطعه کد 26

UDPRemoteCommandProcessor proc = new UDPRemoteCommandProcessor ( 8081, "127.0.0.1", 8080 );

و پورت سرور IP پارامتر 8081 پورت محلی بوده که پردازشگر دستور به آن مقید م ی شود. دو پارامتر دیگر سازنده، آدرس

می باشد که پردازشگر دستور به آن متصل می گردد.

سه TcpCommandProcessor است، را بررسی م ی کنیم. شبیه UdpCommandProcessor حال پردازشگر دستور که بنام

33 را - ابتدا به فیلدهای کلاس نظری م ی افکنیم (قطعه کد 26 .()Execute و مت د ()Close متد دارد : یک سازنده، متد

ببینید).

33- قطعه کد 26

// the local port where the processor is bound to

private int localPort = -1;

// the remote host

private string remoteHost = null;

// the remote port

private int remotePort = -1;

// communication interface

private UdpClient client = null;

به یک پورت خاص مقید می شود. UDP در سازنده، همه فیلدها مقداردهی می شوند و سرویس گیرنده

34- قطعه کد 26

public UDPRemoteCommandProcessor ( int localPort,

string remoteHost, int remotePort )

{

// add parameter checking here

this.localPort = localPort;

this.remoteHost = remoteHost;

this.remotePort = remotePort;

this.client = new UdpClient ( localPort );

}

را فراخوانی می کند. UDP سرویس گیرنده ()Close بسیار ساده است. آن متد ()Close متد

35- قطعه کد 26

public void Close ()

{

this.client.Close ();

}

فصل بیست و ششم برنامه نویسی شبکه

495

است . فقط نحوه اداره کردن ارتباط به دلیل نوع پروتکل TcpCommandProcessor بسیار شبیه به متد ()Execute متد

سیستم محلی و پورت به دستور لازم اس ت . همچنین روش ارسال و IP متفاوت است . کدی برای اضافه کردن آدرس (UDP)

ببینید. UDP 36 را برای کد - دریافت داده ها نیز متفاوت است. قطعه کد 26

36- قطعه کد 26

public bool Execute ( string command, ref string result )

{

// add parameter checking here

bool ret = true;

Console.WriteLine ( "executing command: " + command );

// build the request string

string request = "127.0.0.1:" + this.localPort.ToString ()

+ ":" + command;

Byte[] req = System.Text.Encoding.ASCII.GetBytes (

request.ToCharArray () );

client.Send ( req, req.Length, this.remoteHost,

this.remotePort );

// we don't need an endpoint

IPEndPoint dummy = null;

// receive datagram from server

byte[] res = client.Receive ( ref dummy );

result = System.Text.Encoding.ASCII.GetString ( res );

ret = !result.Equals ( "BYE" );

return ret;

}

-4-3 کامپایل کردن و اجرای مثال -26

راکامپایل کنی د . ابتدا سرور و سپس سرویس UdpHelloWorldClient.CS و UdpHelloWorldServer.CS برنامه

39 را خواهید دی د . حال با فشار دادن هر کلیدی - 38 و 26 - 37 و 26 - گیرنده را اجرا کنی د . پنجره های شکل های 26

برنامه های مورد نظر را ببندید.

37- شکل 26

38- شکل 26

39- شکل 26

را بررسی م یکند. UDP بخش بعدی نحوه نوشتن یک برنامه کاربردی چندپخشی

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

496

UDP -4-26 ایجاد یک تلگراف اخبار بوسیله چندپخشی

تلگراف اخبار 1 برنامه ای است که یک سرور اخبار، پیا م ها را به تعدادی سرویس گیرنده ارسال م ی کند. یک سرویس گیرنده

خود را در سرور ثبت می کند. از آن لحظه به بعد سرویس گیرنده مجاز است پیام های جدید سرور را دریافت کند.

است . همانطور که در UDP می توانید این معم ا ری را به چندین روش پیاد ه سازی کنید . اما ساده ترین روش کاربرد چندپخشی

و یک پورت، نام مستعار یک گروه اس ت . IP مقدمه شرح داده شد، م ی توانید برنامه های کاربردی را هم گروه کنی د . یک آدرس

و پورت، بقیه نظیرهای گروه، آن داده را دریافت خواهند کرد. IP بدین معنی که با ارسال یک داده از طرف یک نظیر به آن

در این بخش، نحوه توسعه یک سرور و سرویس گیرنده تلگراف اخبار ساده را خواهیم دی د . سرور یک برنامه کاربردی ویندوز

با یک کادر متنی و یک دکمه است . کاربر اخبار را در کادر متنی تایپ م یکند. با کلیک روی دکمه، سرور خبرها را به گروه

40 را ببینید). - ارسال می کند( شکل 26

40- شکل 26

سرویس گیرنده یک برنامه کاربردی ویندوز با یک کادر متنی اس ت . اگر اخبار برسند، خبرهای جدید روی این کادر نمایش

41 را ببینید). - به سمت چپ حرکت خواهد کرد(شکل 26 marquee داده خواهند شد و متن داخل کادر بصورت یک

41- شکل 26

NET -1 کاربرد کلی کلا سهای مورد نیاز -4 -26

نیاز داری د . علاوه بر متدهای شرح System.Net.Sockets.UdpClient دیدید، فقط یک کلاس بنام UDP همانطور که در

را UDP را بکار بری د . این متد یک نظیر ()UdpClient.JoinMultiCastGroup داده شده در بخش قبلی، م ی توانید متد

به گروه چندپخشی ثبت م ی کند. مقداردهی اولیه سرور اخبار و سرور گیرنده با همان کد انجام م ی شود . ابتدا یک

به ()JoinMultiCastGroup به یک پورت محلی مقید کنی د . سپس این سرویس گیرنده را با فراخوانی متد UdpClient

برای دریافت داده از آن ایجاد IPEndPoint گروه را م ی گیرد. نهایتا" یک IP گروه چندپخشی ثبت کنی د . این متد آدرس

و یک پورت است. IP ترکیبی از یک آدرس IPEndPoint ، می کنید. همانطور که در مقدمه بیان شده

// create a peer bound to a local port

UdpClient peer = new UdpClient ( LOCAL_PORT );

// create the group IP address

IPAddress groupAddress = IPAddress.Parse ( GROUP_IP );

// add the peer to the group

peer.JoinMulticastGroup ( groupAddress );

1 News ticker

فصل بیست و ششم برنامه نویسی شبکه

497

// create an end point for sending data to the group

IPEndPoint groupEP = new IPEndPoint ( groupAddress,

GROUP_PORT );

است. UDP کد ارسال و دریافت داده شبیه بخش مثال

// send data to the group, d is a byte array

peer.Send ( d, d.Length, groupEP );

// receiving data from the group

IPEndPoint dummy = null;

byte[] d = peer.Receive ( ref dummy );

در بخش بعدی، یک ک لا س که بوسیله سرور و سرویس گیرند ه ی اخبار استفاده م ی شود را شرح م ی دهیم . این کلاس بنام

ایجاد می کند. UdpClient قرار دارد. آن یک واسط ساده برای کلاس Base.cs است و در فایل UDPPeer

سرور می تواند در مد چندپخشی و ت ک پخشی هدایت شود. اگر آن با پورت محلی ایجاد شود، فقط در مد ت ک پخشی فعال

سرور را ()Close تعریف شود، مد چندپخشی فعال اس ت . متد UDP و پورت گروه چندپخشی IP است. اگر با یک آدرس

برای دریافت و ارسال داد ه ها استفاده م ی شوند. حال به جزئیات وارد شده و ()Send و ()Receive متوقف م ی کند و متدهای

42 را ببینید). - با فیلدهای کلاس شروع می کنیم(قطعه کد 26

42- قطعه کد 26

// udp peer

private UdpClient server = null;

// multicast group IP address

private IPAddress groupAddress = null;

// multicast group endpoint (IP address and port)

private IPEndPoint group = null;

groupAddress و group به عنوان یک واسط ارتباطی برای ت ک پخشی یا چندپخشی لازم اس ت . فیلدهای Server فیلد

نقطه انتهایی group است و UDP گروه چندبخشی IP آدرس groupAddress فقط در مد چندپخشی لازم هستن د . فیلد

است که داده به آن ارسال م یشود.

را به یک پورت محلی مقید UDP 43 می بینید. آن بسیار ساده است و فقط یک نظیر - سازنده ی تک پخشی را در قطعه کد 26

می کند.

43- قطعه کد 26

public UDPPeer ( int localPort )

{

// add parameter checking here

Console.WriteLine ( "initializing UDP server, port=" +

localPort + "..." );

this.server = new UdpClient ( localPort );

Console.WriteLine ( "UDP server initialized" );

}

به پورت محلی فراخوانی م ی کند. علاوه براین، نظیر UDP سازنده ی چندپخشی، سازند ه ی تک پخشی را برای مقید کردن نظیر

با IPAddress 44 را ببینی د ). برای عمل ثبت، ا ی جاد یک نمونه از - را به گروه چندپخشی ثبت م ی کند(قطعه کد 26

نمونه ای از کلاس group ارائه م ی شود. فیلد groupAddress گروه لازم اس ت . این آدرس با فیلد IP مقداردهی اولیه آدرس

است و بعدا" برای دریافت داده لازم است. IPEndPoint

44- قطعه کد 26

public UDPPeer ( int localPort, string groupIP,

int groupPort ) : this ( localPort )

{

// add parameter checking here

Console.WriteLine ( "adding UDP server to multicast " +

"group, IP=" + groupIP + ", port=" + groupPort + "...");

this.groupAddress = IPAddress.Parse ( groupIP );

this.group = new IPEndPoint ( this.groupAddress,

groupPort );

this.server.JoinMulticastGroup ( this.groupAddress );

Console.WriteLine ( "UDP server added to group" );

}

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

498

بسیار ساده اس ت . درحالت چندپخشی نظیر را از گروه چندپخشی حذف م ی کند . درنهایت، آن متد ()Close متد

45 را ببینید). - را فراخوانی می کند(قطعه کد 26 ()UdpClient.Close

45- قطعه کد 26

public void Close ()

{

if ( this.groupAddress != null )

this.server.DropMulticastGroup ( this.groupAddress );

this.server.Close ();

}

46 را ببینی د ). رشته بایتی دریافتی به یک - اداره کردن آرایه بایتی را کپسوله م ی کند( قطعه کد 26 ،()Receive متد ساده ی

رشته تبدیل می گردد و به فراخواننده ی این متد برگردانده م یشود.

46- قطعه کد 26

public String Receive ()

{

IPEndPoint dummy = null;

// receive datagram

byte[] data = this.peer.Receive ( ref dummy );

return new System.Text.ASCIIEncoding ().GetString (

data );

}

را فراخوانی UDP نظیر ()Send نیز ساده اس ت . بعد از تبدیل رشته داده شده به یک آرایه بایتی، متد ()Send متد

47 را ببینید). - می کند(قطعه کد 26

47- قطعه کد 26

public void Send ( string message )

{

// add parameter checking here

Console.WriteLine ( "sending " + message + "..." );

// convert news string to a byte array

Byte[] d = System.Text.Encoding.ASCII.GetBytes (

message.ToCharArray () );

this.server.Send ( d, d.Length, this.group );

Console.WriteLine ( "message sent" );

}

بخش بعدی واسط کاربری سرور را شرح م یدهد.

-2 سرور -4 -26

نامگذاری UDPNewsServer توسعه یک کلاس واسط برای سرور اخبار را ساده م ی کند . کلاس سرور UDPpeer کلاس

قرار می گیرد. UDPNewsServer.CS می شود و در فایل

این کلاس یک سازنده و سه متد دار د : یک اداره ک ن نده رویداد برای رویداد بستن پنجره، یک اداره کننده رویداد برای دکمه

و یک متد که توسط ریسمان برای ارسال اخبار استفاده م یشود.

مشتق م ی شود. ابتدا فیلدهای این کلاس را بررسی م ی کنیم(قطعه System.Windows.Forms.Form کلاس سرور اخبار از

48 را مشاهده کنید). - کد 5

48- قطعه کد 26

// local port where the UDP server is bound to

private const int LOCAL_PORT = 8080;

// multicast group IP address

private const string GROUP_IP = "225.0.0.1";

// multicast group port

private const int GROUP_PORT = 8081;

// UDP server

private UDPPeer server = null;

// a thread for sending new continuously

private Thread serverThread = null;

// a data field for typing in a new message

فصل بیست و ششم برنامه نویسی شبکه

499

private TextBox text = null;

// a button for setting the new message

private Button setButton = null;

// the news message

private string news = "";

کلیک Send مقداردهی اولیه را انجام م یدهد. اگر دکمه UI 49 کد سازنده را نشان م ی دهد که قبل از نمایش - قطعه کد 26

شود، باید سرور اخبار، اخبار ارسال شده به گروه چندپخشی را بروز کن د . به منظور دریافت یک اخطار بوسیله دکمه، متد

برای رویداد بستن پنجره ثبت م ی شود . در ()OnClose را به عنوان اداره کننده رویداد کلیک ثبت کنی د . متد ()OnSet

بطور پیوسته اخبار تایپ شده در کادر متنی را ارسال م یکند. ()Run نهایت یک ریسمان بوسیله متد

49- قطعه کد 26

public UDPNewsServer ()

{

// UI components initialization

// add an event listener for click-event

this.setButton.Click += new System.EventHandler ( OnSet );

// add an event listener for close-event

this.Closed += new System.EventHandler ( OnClosed );

// create communication components

this.server = new UDPPeer ( LOCAL_PORT, GROUP_IP,

GROUP_PORT );

// start communication thread

this.serverThread = new Thread (

new ThreadStart ( Run ) );

this.serverThread.Start ();

Console.WriteLine ( "initialization complete" );

}

50 را - چون باید ارسال پیا م ها پیوسته باشد، استفا د ه از ریسمان لازم اس ت . حال ریسمان را بررسی م ی کنیم (قطعه کد 26

کلاس را به گروه چندپخشی ارسال م یکند و یک پیام روی کنترل م ینویسد تا نشان news ببینید). هر ثانیه محتوای فیلد

ری سمان را به مدت یک ثانیه مسکوت ()Sleep دهد در حال ارسال داده اس ت . بعد از ارسال داده، این متد با فراخوانی متد

نگه می دارد.

50- قطعه کد 26

// sending thread

public void Run ()

{

while ( true )

{

if ( !this.news.Equals ( "" ) )

{

Console.WriteLine ( "sending " + this.news );

this.server.Send ( this.news );

}

// wait one second

Thread.Sleep ( 1000 );

}

}

51 را ببینید). - مقداردهی می شود(قطعه کد 26 set در رویداد کلیک دکمه news فیلد

51- قطعه کد 26

// button click event handler

public void OnSet ( Object sender, EventArgs e )

{

this.news = this.text.Text;

}

فرم قرار م ی گیرد. این متد در ریسمان ارسال کننده داده با Closed نهایتا" کد توقف ارتباط را ملاحظه کن ی د. آن در رویداد

ریسمان ()Join کار را متوقف م ی کند، تا زمانیکه پروس ه ی پدر از بین رو د ( این عمل با فراخوانی متد ()Abort اجرای متد

52 را مشاهده کنید). - فراخوانی می شود(قطعه کد 26 UDPPeer شی ()Close امکان پذیر است). بعد از آن، متد

52- قطعه کد 26

public void OnClosed ( Object sender, EventArgs e )

{

Console.WriteLine ( "server shut down..." );

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

500

// stop thread

this.serverThread.Abort ();

// wait until it's stopped

this.serverThread.Join ();

this.server.Close ();

Application.Exit ();

}

-3 سرویس گیرنده -4 -26

و یک واسط کارب ر . کلاس سرویس UDP سرویس گیرنده به دو بخش تقسیم م ی شود: یک کلاس سرویس گیرنده چندپخشی

قرار دارد. base.cs است که در فایل UDPMultiCastClient گیرنده بنام

دراین مثال یک ارتباط ناهمگام را توسعه م ی دهیم. یک مثال از ارتباط ناهمگام صحبت کردن با دوست از طریق پست

است . شما یک پیام به دوست خود ارسال م ی کنید و م ی توانید کار دیگری انجام دهید، نه اینکه منتظر chat الکترونیکی یا

جواب بمانید . بعد از اینکه جواب دوست شما دریافت شود، به شما اطلاع داده م ی شود. این یک مثال ناهمگام است، یعنی

اینکه واسط کاربری سرویس گیرنده م ی تواند استفاده شود، در حالیکه یک ریسمان در پس زمینه منتظر داد ه های ورودی

است. اما زمانی که ریسمان یک پیام بگیرید، باید واسط کاربری را مطلع ساز د . این عمل بوسیله ریسمان با فرخواخوانی یک

53 معماری سرویس گیرنده را نشان م ی دهد . - نماینده که د ر فرم واسط کاربری پیاد ه سازی شده انجام م ی شود. شکل 26

و ریسمان دریافت کننده. واسط کاربری ticker سرویس گیرنده از سه قطعه اصلی ساخته م ی شود: واسط کاربری، ریسمان

کارکترهای کادر متنی را کارکتر به کارکتر به چپ انتقال م یدهد. ticker یک فرم ساده با یک کادر متنی است. ریسمان

پیاده سازی می شود و بطور مدام به پیا م های ورودی گوش می کند. اگر UDPMultiCastClient ریسمان دریافت کننده در

پیاده سازی شده است، فراخوانی م ی کند . نماین ده ی ()SetNows را که با متد ()Notify یک پیام برسد، آن نمایند ه ی

قرار دار د . آن تا حدی شبیه یک اداره کنند ه ی Base.CS 54 نشان داده م ی شود. آن در فایل - در قطعه کد 26 ()Notify

رویداد ____________است. اگر ریسمان یک پیام جدید دریافت کند، نماینده را با ارسال پیام به آن فراخوانی م یکند.

53- شکل 26

54- قطعه کد 26

public delegate void Notify ( string text );

یک واسط برای سوک تهای ویندوز ایجاد م یکند. علاوه بر این، این کلاس System.Net.Sockets.Socket نکته: کلاس

یا ()Accept فراهم م یکن د. برای همه متدها همچون Socket و در کلاس DLL متدهایی برای ارتباط ناهمگام در این

وجود ()EndRecive و ()BeginRecieve یا ()EndAccept و ()BeginAccept متدهای ناهمگام ش بیه ()Receive

فصل بیست و ششم برنامه نویسی شبکه

501

انتظار ناهمگامی برای یک اتصال ورودی معرفی م یکند. زمانی که یک اتصال پذیرفته ()BeginAccept ، دارد. برای مثال

فراخوانی شود. AsyncCallback شود، یک نماینده بنام

را UDP بررسی می گردد. آن یک سازنده و دو متد دار د . سازنده، سرویس گیرند ه ی UDPMultiCastClient حال کد

یک ریسمان جهت گوش دادن به اخبار ()Run مقداردهی اولیه م ی کند، که از سرور اخبار پیا م ها را دریافت م ی کند. متد

سرویس گیرنده را متوقف م ی سازد. ما حداقل سه فیلد ک لا س نیاز داری م . یک نمایند ه ی ()Close استفاده می کند و متد

55 را ببینید). - اخطار، قطعات ارتباط و یک ریسمان برای دریافت ناهمگام داده (قطعه کد 26

55- قطعه کد 26

// notification delegate

private Notify notify = null;

// communication interface

private UDPPeer peer = null;

// receiving thread

private Thread clientThread = null;

گروه و پورت مقداردهی اولیه م ی کند. در نهایت، IP را با آدرس UDP توسط سازنده ذخیره م ی شود و نظیر Notify نماینده

.(56- ریسمان دریافت کننده ی اخبار را راه اندازی م یکند( قطعه کد 26

56- قطعه کد 26

public UDPMulticastClient ( string groupIP, int groupPort,

Notify notify )

{

// add parameter validation here

Console.WriteLine ( "initializing UDP multicast " +

"client, group=" + groupIP + ", port=" + groupPort +

"..." );

this.notify = notify;

// create communication components

this.client = new UDPPeer ( groupPort, groupIP,

groupPort );

// start listener thread

this.clientThread = new Thread (

new ThreadStart ( Run ) );

this.clientThread.Start ();

Console.WriteLine ( "UDP multicast client initialized" );

}

پیاده سازی می شود. آن یک حلقه ب ی نهایت است که داد ه های موجود را دریافت ()Run ریسمان دریافت کننده بوسیله متد

.(57- می دهد(قطعه کد 26 Notify می کند و آن را به نماینده

57- قطعه کد 26

public void Run ()

{

while ( true )

this.notify ( this.peer.Receive () );

}

مربوط به ()Close سرویس گیرنده را م توقف می سازد. آن ریسمان دریافت کننده را متوقف م ی سازد و متد ()Close متد

.(58- آن را فراخوانی می کند(قطعه کد 26 UDP نظیر

58- قطعه کد 26

public void Close ()

{

this.clientThread.Abort ();

this.clientThread.Join ();

this.peer.Close ();

}

ارائه شده اس ت . حال، واسط کاربری سرویس گیرنده را بررسی م ی کنیم . واسط UDP تا اینجا، سرویس گ ی رنده چندپخشی

نامیده م ی شود و در فایل UDPNewsCleint مشتق م ی شود و System.Windows.Forms.Form کاربری از کلاس

قرار دار د . آن یک کادر متنی ساده دار د . این کلاس یک سازنده و چه  ار متد دار د . در سازنده UDPNewsClient.CS

اسلام احمد زاده - 09177112161 - C# برنامهنویسی

502

برای رویداد ()OnClosed مقدار دهی اولیه برنامه کاربردی انجام م ی شود. علاوه بر این، یک متد اداره کننده رویداد بنام

()SetNews برای انتقال دادن کاراکترهای کادر متنی به چپ و متد ()RunTicker ثبت م ی شود. نهایتا" متدهای ()Closed

برای ____________بروزکردن اخبار کادر متنی UDPMultiCastClient را پیاد ه سازی می کند و ریسمان گوش کننده ()Notify نماینده

59 ملاحظه کنید. - استفاده می شود. ابتدا فیلدهای کلاس را در قطعه کد 26

59- قطعه کد 26

// multicast group IP address

private const string GROUP_IP = "225.0.0.1";

// multicast group port

private const int GROUP_PORT = 8081;

// communication interface

private UDPMulticastClient client = null;

// ticker thread

private Thread tickerThread = null;

// new messages

private TextBox text = null;

// default news displayed at the beginning

private string news = "Please wait...";

60 سازنده را بدون - را مقداردهی م ی کند. قطعه کد 26 ticker و ریسمان UDP سازنده کادر متنی، اداره کننده رویداد، نظیر

مقداردهی اولیه کادر متنی نشان می دهد.

60- قطعه کد 26

public UDPNewsClient ()

{

// initialize UI

// add an event listener for close-event

this.Closed += new System.EventHandler ( OnClosed );

// start communication thread

this.client = new UDPMulticastClient ( GROUP_IP,

GROUP_PORT, new Notify ( SetNews ) );

// start ticker thread

this.tickerThread = new Thread (

new ThreadStart ( RunTicker ) );

this.tickerThread.Start ();

Console.WriteLine ( "initialization complete" );

}

61 ). آن سرویس گیرنده را بسته و - فراخوانی م ی شود(قطعه کد 26 Closed متد توقف سرویس گیرنده اخبار بوسیله رویداد

را متوقف می سازد. ticker ریسمان

61- قطعه کد 26

public void OnClosed ( Object sender, EventArgs e )

{

Console.WriteLine ( "client shut down" );

this.client.Close ();

this.tickerThread.Abort ();

this.tickerThread.Join ();

Application.Exit ();

}

هر 500 میلی ثانیه یک ک ا رکتر را به سمت چپ انتقال م ی دهد و کارکتر سمت چپ را حذف م ی کند . ticker ریسمان

را نشان م ی دهد . آن پیام دریافتی ()Notify پیاده سازی آن زیاد هوشمند نیست، اما برای شبی ه سازی کافی اس ت . متد

بوسیله سرویس گیرنده چندپخشی را در متغیر اخبار قرار م یدهد.

62- قطعه کد 26

public void RunTicker ()

{

// initialze the textbox with the default text

this.text.Text = " -+-+- " + this.news + " -+-+- " +

this.news + " -+-+- ";

while ( true )

{

string data = this.news + " -+-+- ";

// repeat as long as there are characters in the data string

while ( !data.Equals ( "" ) )

{

فصل بیست و ششم برنامه نویسی شبکه

503

// wait 500 milliseconds

Thread.Sleep ( 500 );

// remove the first character from the text field and add the

// first character of the data string

this.text.Text = this.text.Text.Substring ( 1 ) +

data[0];

// remove the first character from the data string

data = data.Substring ( 1 );

}

}

}

// notification method, used by multicast client

public void SetNews ( string news )

{

this.news = news;

}

-4 کامپایل کردن و اجرای مثال -4 -26

را ایجاد کنی د . سپس آنها را UDPNewsServer.exe و UDPNewsClient.exe ابتدا فایل های مورد نظر را کامپایل کرده و

اجرا کرده و تست کنید.

65 ظاهر - بعد از مدتی شکل 26 set 64 ظاهر م ی گردد و با تایپ یک پیام و کلیک روی - 63 ، سپس شکل 26 - ابتدا شکل 26

خواهد شد.

63- شکل 26

64- شکل 26

65- شکل 26

Mohsen_mahyar@yahoo.com - C# برنامه نویسی

 

   + MOHSEN GHASEMI - ۸:۳٤ ‎ق.ظ ; ۱۳۸٩/٥/٢