برای برنامه نویسی شبکه با پروتکل UDP در جاوا نیاز مند بررسی پکیج شبکه (java.net) در جاوا هستیم. از آنجا که این بسته بسیار بزرگ است توضیح آن از این مقوله خارج است. از این رو، ما تنها امکانات UDP و شیوه استفاده از آن را بررسی خواهیم نمود.
UDP دقیقه نقطه مقابل TCP است. پروتکل HTTP که هر روزه از آن استفاده می شود از TCP استفاده می نماید.
اگر علاقه مند هستید در مورد HTTP 2 بدانید سری به مقاله HTTP/2 چگونه کار میکند بیندازید.
۱. بررسی اجمالی
udp پروتکلی عجول است. داده ها را ارسال می کند غافل از آنکه ممکن است به مقصد نرسیده باشند. در نتیجه این پروتکل اطمینان حاصل نمی کند که آیا بسته ارسالی به مقصد رسیده است یا خیر.
۲. چرا از UDP استفاده کنیم؟
سرعت از مزایای UDP است. این پروتکل اطمینان را فدای سرعت نموده است. اگر به هر دلیلی ارتباط قطع گردد، داده مورد نظر از دست خواهد رفت. اما در شیوه های ارتباطی که سرعت بالا از همه چیز مهم تر است، این پروتکل کمک زیادی می کند.
نمونه های کاربرد:
- پخش فیلم
- ارسال صوت در مکالمات تلفنی
- پخش زنده شبکه های تلوزیونی
- ارسال پیام در بیسیم ها
عیب TCP بخاطر سربار بالا است، از این رو در مواقعی که نیاز به سرعت بیشتر داریم UDP کاربرد خواهد داشت.
دلیل استفاده از زبان برنامه نویسی جاوا وجود ابزار آماده داخلی برای ارتباط UDP است. از طرفی یک زبان کامپایلیری است که به زبان انسان نزدیک است. کاربرد و وسعت استفاده از زبان جاوا هم بر کسی پوشیده نیست.
پروتکل UDP به دلیل سادگی و وظایف کم نیاز به سیستم عامل و نرم افزار پیچیده ندارد. پس می توان آن را روی سبک ترین سیستم ها برنامه نویسی کرد. به همین دلیل ، می توان توسط یک سیستم به کوچک ترین سیستم ها نیز متصل گردید.
عیب UDP عدم اجرای عملیات دست تکانی است. اگر بسته هایی داشتید که می بایست از رسیدن آنها به مقصد مطمئن شوید از TCP استفاده نمایید. جاوا برای TCP ها ابزار های خوبی فراهم نموده است.
۳. ساخت یک نرم افزار با udp
برنامه ای که قصد اجرای آن را داریم دو قسمت سرور و کلاینت دارد که ارتباطات آنها به شکل زیر است:
- سرور یک پورت را دریاف و به آن گوش میدهد.
- کلاینت پیام مورد نظر را به سرور ارسال می کند.
- سرور پیام کلاینت را دریافت و به خودش باز می گرداند.
- کلاینت مجدد پیام را دریافت کرده و در خروجی نمایش می دهد.
اصل کار همین است و با یک سناریو خوب می توانید برنامه های خوبی در این زمینه بنویسید. حال بیایید به عملی نمودن این سناریو بپردازیم.
۴. ساخت سرور و اختصاص پورت
public class EchoServer extends Thread { private DatagramSocket socket; private boolean running; private byte[] buf = new byte[256]; public EchoServer() { socket = new DatagramSocket(4445); } public void run() { running = true; while (running) { DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); String received = new String(packet.getData(), 0, packet.getLength()); if (received.equals(\"end\")) { running = false; continue; } socket.send(packet); } socket.close(); } }
بسته های زیر استفاده می گردند.
DatagramSocket: یک کلاس جاوا برای برقراری ارتباط است. بنا بر این شما توسط اینکلاس داده ارسال می کنید.
DatagramPacket: این کلاس قالب داده های شما است. بسته هایی که ارسال می کنید در شئ هایی از این کلاس قرار داده می شوند.
InetAddress: آدرس و پورت شبکه توسط اشیایی با قالب این کلاس تعریف می شوند.
آرایه buf: ظرفی است برای برداشتن اطلاعات از بستر شبکه.
running: یک متغیر است که وضعیت برنامه را نگهداری می کند. اگر false شود برنامه سرور متوقف خواهد شد.
در کد سرور اطلاعات با قالب DatagramPacket و توسط کلاس DatagramSocket ردوبدل می شوند. از این رو یک حلقه بی انتهای while وجود دارد که تنها در صورت false شدن متغیر running متوقف خواهد شد.
در نتیجه کلاینت با ارسال پیام end میتواند سرور را متوقف کند.
برای سادگی کار از کلاس Thread استفاده شده است. این کلاس یک نخ جدا ایجاد می کند. از این رو، هر کدی که در متد run قرار میگیرد توسط این نخ اجرا می گردد. ما نیز حلقه while را در این متد قرار می دهیم.
در ابتدای حلقه while یک شئ از نوع DatagramPacket ایجاد میگردد تا اطلاعات کلاینت توسط آن نگهداری شود. ما به این شئ نیاز داریم تا بتوانیم به کلاینت ارسال کننده پیام پاسخ دهیم.
پس از آن، متد receive اجرا می گردد این متد نخ مورد نظر را متوقف خواهد نمود تا پیامی از یک کلاینت دریافت گردد.
پس از دیافت پیام، آدرس ip و شناسه پورت کلاینت را دریافت میکند تا آماده بازگردانی پیام باشد.
بعد، یک شی از نوع DatagramPacket ایجاد می کند و پیام پاسخ را ارسال مس نماید.
تفاوت اساسی بسته دوم با بسته اول آدرس ip و پورتکلاینت است که در شئ قبلی نیاز به تعریف آنها نبود.
۵. ساخت کلاینت و نمایش پیام
public class EchoClient { private DatagramSocket socket; private InetAddress address; private byte[] buf; public EchoClient() { socket = new DatagramSocket(); address = InetAddress.getByName(\"localhost\"); } public String sendEcho(String msg) { buf = msg.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String( packet.getData(), 0, packet.getLength()); return received; } public void close() { socket.close(); } }
ساختار کد کلاینت با سرور فرق زیادی ندارد. در این کد ۲ متغیر عمومی (global) زیر استفاده شده است.
socket از نوع DatagramSocket و address که آدرس سرور را نگهداری میکند و از نوع InetAddress می باشد.
ما ابتدا به ساکن متن پیام کلاینت را آماده می کنیم. آن را برای سرور با یک شئ از نوع DatagramPacket ارسال می کنیم.
پس از ارسال به سرعت متن پیام نمایش داده می شود چرا که با دریاف پیام، خیلی سریع، بایت ها به متن تبدیل می گردند و نمایش داده می شوند.
۶. بررسی نتیجه
در هر کدام از کلاس ها یک متد main (اصلی) جاوا قرار دهید.
ابتدا سرور را توسط دستور javac کامپایل کرده و سپس توسط دستور جاوا اجرا کنید.
پس از آن همین کار را برای کلاینت نیز انجام دهید.
از طریق تست نویسی هم می توان به کار کردن صحیح برنامه پی برد.
public class UDPTest { EchoClient client; @Before public void setup(){ new EchoServer().start(); client = new EchoClient(); } @Test public void whenCanSendAndReceivePacket_thenCorrect() { String echo = client.sendEcho(\"hello server\"); assertEquals(\"hello server\", echo); echo = client.sendEcho(\"server is working\"); assertFalse(echo.equals(\"hello server\")); } @After public void tearDown() { client.sendEcho(\"end\"); client.close(); } }
7. خلاصه
در نوشته برنامه نویسی شبکه با پروتکل udp در جاوا یک سرور و یک کلاینت با جاوا ایجاد کردیم که با یکدیگر تعامل داشتند و برای ارتباطات خود از پروتکل UDP استفاده نمودند. و نتیجه آن را توسط یک کلاس تست مورد ارزیابی قرار دادیم.