Tip 18 Java: Menerapkan fitur batas waktu untuk JDK 1.0.2 DatagramSocket

Jika Anda telah mengembangkan aplikasi Java yang menggunakan soket Datagram untuk mengirim dan menerima pesan, Anda mungkin mengalami kebutuhan untuk menerapkan fitur batas waktu untuk membuka blokir DatagramSocketmetode terima. Tanpa fitur waktu tunggu, aplikasi Anda akan memblokir hingga menerima pesan, dan karena pengiriman Datagram tidak dijamin, aplikasi Anda dapat memblokir untuk waktu yang sangat lama. Tip Java ini akan menjelaskan teknik untuk mengatur waktu habis dan membuka blokir DatagramSocketmetode terima.

Anda mungkin sudah menduga bahwa teknik ini akan menggunakan benang. Pemrograman thread di Java cukup menyenangkan. Orang bisa membandingkannya dengan kegembiraan bermain ski di Danau Tahoe atau berlayar di dekat pantai Santa Cruz. (Oke, mungkin tidak terlalu menyenangkan, tapi tetap menyenangkan!)

Saat memikirkan metode untuk menyelesaikan fitur batas waktu, mungkin skema pertama dan paling jelas yang terlintas dalam pikiran adalah menempatkan fungsionalitas penerimaan DatagramSocket ke dalam utas terpisah dan kemudian meluncurkan utas lain sebagai pengatur waktu yang, setelah kedaluwarsa, akan mematikan penerima utas jika masih hidup. Meskipun metode ini akan berhasil, mungkin ini bukan cara yang paling baik untuk menyelesaikan tugas.

Alih-alih membunuh utas yang diblokir pada metode terima, saya menginginkan solusi yang lebih anggun - yang akan membuka blokir metode terima. Untuk mencapai ini, saya membutuhkan utas yang mampu mengirim pesan datagram ke utas penerima untuk membuka blokir utas penerima setelah periode batas waktu telah kedaluwarsa. Thread waktu tunggu diimplementasikan sebagai kelasnya sendiri, dan thread penerima membuat instance dari kelas waktu tunggu sebelum memblokir metode terima. Kode berikut menunjukkan implementasi kelas batas waktu. Perhatikan bahwa, untuk singkatnya, penanganan pengecualian dihilangkan.

impor java.io. *; import java.net. *; import java.lang. *; kelas publik DatagramWatchdogTimer mengimplementasikan Runnable {DatagramWatchdogTimer (int timeoutSeconds) melempar SocketException {timeout = timeoutSeconds; socket = DatagramSocket baru (); datagramPort = socket.getLocalPort (); Thread thisThread = Thread baru (ini); thisThread.start (); } public int getPort () {return datagramPort; } public void run () {// buat pesan balasan standar yang menunjukkan // pesan berasal dari DatagramWatchdogTimer // dalam kasus saya, nol sudah cukup. String replyStr = new Integer (0) .toString (); byte [] replyBuf = byte baru [replyStr.length ()]; replyStr.getBytes (0, replyStr.length (), replyBuff, 0); int replyLength = replyStr.length (); // menerima pesan dari untaian penerima. // ini diperlukan agar kita tahu bagaimana mengirim pesan // unblocking kembali padanya.byte [] buffer = bute baru [128]; Paket DatagramPacket = DatagramPacket baru (buffer, buffer.length); socket.receive (paket); // tunggu beberapa detik waktu tunggu dan kemudian kirim kembali // pesan untuk membuka blokir. Thread.sleep (batas waktu * 1000); int requestorPort = packet.getPort (); InetAddress requestorAddress = packet.getAddress (); DatagramPacket sendPacket = DatagramPacket baru (replyBuff, replyLength, requestorAddress, requestorPort); DatagramSocket sendSocket = new DatagramSocket (); sendSocket.send (sendPacket); } batas waktu int pribadi; private int datagramPort; soket DatagramSocket pribadi; }getPort (); InetAddress requestorAddress = packet.getAddress (); DatagramPacket sendPacket = DatagramPacket baru (replyBuff, replyLength, requestorAddress, requestorPort); DatagramSocket sendSocket = new DatagramSocket (); sendSocket.send (sendPacket); } batas waktu int pribadi; private int datagramPort; soket DatagramSocket pribadi; }getPort (); InetAddress requestorAddress = packet.getAddress (); DatagramPacket sendPacket = DatagramPacket baru (replyBuff, replyLength, requestorAddress, requestorPort); DatagramSocket sendSocket = new DatagramSocket (); sendSocket.send (sendPacket); } batas waktu int pribadi; private int datagramPort; soket DatagramSocket pribadi; }

Seperti disebutkan di atas, setiap kali aplikasi Anda perlu menerima pesan datagram, itu bisa membuat instance DatagramWatchdogTimerkelas untuk menyetel periode waktu tunggu. Jika aplikasi tidak menerima pesan nyata dalam hitungan detik waktu tunggu, itu akan membuka blokir dengan menerima pesan buka blokir dari DatagramWatchdogTimerkelas.

Berikut ini contohnya:

// kode aplikasi int timeoutSeconds = 5; InetAddress myAddress = InetAddress.getByName (""); // buat turunan dari kelas pengatur waktu DatagramWatchdogTimer wdTimer = new DatagramWatchdogTimer (timeoutSeconds); int wdPort = wdTimer.getPort (); // kirim pesan ke wdTimer untuk memulai timer // msgBuff bisa menjadi apapun yang Anda inginkan. String msgString = new String ("time me"); byte [] msgBuff = byte baru [msgString.length ()]; msgString.getBytes (0, msgString.length (), msgBuff, 0); DatagramSocket socket = new DatagramSocket (); DatagramPacket wdPacket = DatagramPacket baru (msgBuff, msgLength, myAddress, wdPort); socket.send (wdPacket); // sekarang Anda dapat membaca dari soket dan memiliki jaminan // bahwa Anda hanya akan memblokir untuk timeoutSeconds. byte [] buffer = byte baru [1024]; Paket DatagramPacket = DatagramPacket baru (buffer,buffer.length); socket.receive (paket); if (myAddress.equals (packet.getAddress) == true) {// menerima pesan dari objek timer} else {// menerima pesan nyata}

Saat menggunakan teknik ini, pastikan untuk menggunakan DatagramSocket yang sama untuk mengirim ke objek DatagramWatchdogTimer dan untuk menerima datagram. Ini memastikan bahwa objek DatagramWatchdogTimer tahu ke mana harus mengirim pesan buka blokir. Selain itu, dalam kode contoh yang ditunjukkan di atas, port yang dialokasikan secara dinamis digunakan dengan membuat instance DatagramSocket () tanpa argumen apa pun. Ini juga akan bekerja menggunakan port terkenal pilihan Anda seperti DatagramSocket (8000). Terakhir, Anda mungkin ingin objek pengatur waktu mengirim lebih dari satu pesan pembuka blokir - hanya untuk meningkatkan kemungkinannya diterima oleh aplikasi. Ini seharusnya tidak menjadi masalah karena objek pengatur waktu berjalan sebagai utas pada mesin yang sama dengan aplikasi.

Albert Lopez adalah anggota staf teknis di Sun Microsystems dari tahun 1989 hingga 1995. Ia baru-baru ini bergabung dengan staf Sistem Informasi di Chicago Board of Trade, di mana ia adalah anggota utama tim pengembangan Java yang mengembangkan generasi berikutnya sistem perdagangan elektronik menggunakan Java.

Artikel ini, "Tip Java 18: Menerapkan fitur batas waktu untuk JDK 1.0.2 DatagramSocket" pada awalnya diterbitkan oleh JavaWorld.