1. Gambaran keseluruhan
Dalam artikel ini, kita akan menjelajah komunikasi jaringan dengan Java, melalui User Datagram Protocol (UDP).
UDP adalah protokol komunikasi yang menghantar paket bebas melalui rangkaian tanpa jaminan kedatangan dan tidak ada jaminan pesanan penghantaran .
Sebilangan besar komunikasi melalui internet berlaku melalui Transmission Control Protocol (TCP), namun, UDP mempunyai tempatnya yang akan kita terokai di bahagian berikutnya.
2. Mengapa Menggunakan UDP?
UDP agak berbeza dengan TCP yang lebih biasa. Tetapi sebelum mempertimbangkan kelemahan permukaan UDP, penting untuk memahami bahawa kekurangan overhead dapat menjadikannya lebih cepat daripada TCP.
Terlepas dari kepantasan, kita juga perlu ingat bahawa beberapa jenis komunikasi tidak memerlukan kebolehpercayaan TCP tetapi sebaliknya menilai latensi rendah. Video adalah contoh aplikasi yang baik yang mungkin mendapat keuntungan daripada menjalankan UDP dan bukannya TCP.
3. Membangun Aplikasi UDP
Membangun aplikasi UDP sangat mirip dengan membina sistem TCP; satu-satunya perbezaan adalah kita tidak menjalin hubungan antara titik dengan pelanggan dan pelayan.
Penyediaannya juga sangat mudah. Java dihantar dengan sokongan rangkaian terbina dalam untuk UDP - yang merupakan sebahagian daripada pakej java.net . Oleh itu untuk melaksanakan operasi rangkaian lebih UDP, kita hanya perlu mengimport kelas dari java.net pakej: java.net.DatagramSocket dan java.net.DatagramPacket .
Dalam bahagian berikut, kita akan belajar bagaimana merancang aplikasi yang berkomunikasi melalui UDP; kami akan menggunakan protokol gema yang popular untuk aplikasi ini.
Pertama, kami akan membina pelayan echo yang menghantar balik semua mesej yang dihantar kepadanya, kemudian pelanggan echo yang hanya menghantar sebarang mesej sewenang-wenangnya ke pelayan dan akhirnya, kami akan menguji aplikasinya untuk memastikan semuanya berfungsi dengan baik.
4. Pelayan
Dalam komunikasi UDP, satu pesan dikemas dalam DatagramPacket yang dihantar melalui DatagramSocket .
Mari mulakan dengan menyediakan pelayan mudah:
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(); } }
Kami membuat DatagramSocket global yang akan kami gunakan untuk menghantar paket, array byte untuk membungkus mesej kami, dan pemboleh ubah status yang disebut running .
Untuk kesederhanaan, pelayan memperluas Thread , jadi kami dapat menerapkan semua yang ada dalam kaedah jalankan .
Inside run , kami membuat loop sementara yang hanya berjalan sehingga berjalan diubah menjadi false oleh beberapa kesalahan atau mesej penamatan dari klien.
Di bahagian atas gelung, kami menyediakan DatagramPacket untuk menerima mesej masuk.
Seterusnya, kami memanggil kaedah penerimaan pada soket. Kaedah ini menyekat sehingga mesej tiba dan menyimpan mesej di dalam array byte DatagramPacket yang diteruskan kepadanya.
Setelah menerima mesej, kami mengambil alamat dan port klien, kerana kami akan menghantar respons
belakang.
Seterusnya, kami membuat DatagramPacket untuk menghantar mesej kepada pelanggan. Perhatikan perbezaan tandatangan dengan paket penerima. Yang ini juga memerlukan alamat dan port klien yang kami kirimkan.
5. Pelanggan
Sekarang mari kita melancarkan pelanggan mudah untuk pelayan baru ini:
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(); } }
Kodnya tidak berbeza dengan pelayan. Kami mempunyai DatagramSocket global dan alamat pelayan kami. Kami menunjukkan ini di dalam konstruktor.
Kami mempunyai kaedah tersendiri yang menghantar mesej ke pelayan dan mengembalikan respons.
Mula-mula kami menukar mesej rentetan menjadi array byte, kemudian membuat DatagramPacket untuk menghantar mesej.
Seterusnya - kami menghantar mesej. Kami segera menukar DatagramPacket menjadi penerima.
Apabila gema tiba, kami menukar bait menjadi rentetan dan mengembalikan rentetan.
6. Ujian
Dalam kelas UDPTest.java , kami hanya membuat satu ujian untuk memeriksa kemampuan menggema kedua aplikasi kami:
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(); } }
Dalam persediaan , kami memulakan pelayan dan juga membuat klien. Semasa dalam kaedah tearDown , kami mengirim mesej penamatan ke pelayan sehingga dapat ditutup dan pada masa yang sama kami menutup klien.
7. Kesimpulannya
Dalam artikel ini, kami telah mengetahui tentang Protokol Datagram Pengguna dan berjaya membina aplikasi pelayan pelanggan kami sendiri yang berkomunikasi melalui UDP.
Untuk mendapatkan kod sumber penuh untuk contoh yang digunakan dalam artikel ini, anda boleh melihat projek GitHub.