Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗jvSpUdExc 311 of 322 menu
◀ ▶

Обмен UDP-сообщениями в Java

Полный цикл в одной программе: фоновый поток слушает порт, читает запрос и шлёт ответ. Главный поток узнаёт номер порта, отправляет датаграмму и ждёт ответ на том же DatagramSocket.

Синхронизацию порта удобно делать через CountDownLatch: приёмник сигнализирует после getLocalPort, затем отправитель работает. Ответ отправитель печатает строкой из байтов:

import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; public class Main { public static void main(String[] args) throws Exception { CountDownLatch ready = new CountDownLatch(1); int[] port = new int[1]; Thread receiver = new Thread(() -> { try (DatagramSocket socket = new DatagramSocket(0)) { port[0] = socket.getLocalPort(); ready.countDown(); byte[] buf = new byte[256]; DatagramPacket packet = new DatagramPacket( buf, buf.length, ); socket.receive(packet); byte[] reply = "pong".getBytes( StandardCharsets.UTF_8, ); DatagramPacket out = new DatagramPacket( reply, reply.length, packet.getAddress(), packet.getPort(), ); socket.send(out); } catch (Exception ex) { throw new RuntimeException(ex); } }); receiver.start(); ready.await(); try (DatagramSocket socket = new DatagramSocket()) { byte[] data = "ping".getBytes( StandardCharsets.UTF_8, ); DatagramPacket packet = new DatagramPacket( data, data.length, InetAddress.getByName("127.0.0.1"), port[0], ); socket.send(packet); byte[] answerBuf = new byte[256]; DatagramPacket answer = new DatagramPacket( answerBuf, answerBuf.length, ); socket.receive(answer); System.out.println( new String( answer.getData(), 0, answer.getLength(), StandardCharsets.UTF_8, ), ); } } }

Тот же каркас подходит для других коротких фраз. Главное не закрывать сокет отправителя до receive ответа и держать приёмник в потоке, пока идёт обмен:

import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.nio.charset.StandardCharsets; import java.util.concurrent.CountDownLatch; public class Main { public static void main(String[] args) throws Exception { CountDownLatch ready = new CountDownLatch(1); int[] port = new int[1]; Thread receiver = new Thread(() -> { try (DatagramSocket socket = new DatagramSocket(0)) { port[0] = socket.getLocalPort(); ready.countDown(); byte[] buf = new byte[256]; DatagramPacket packet = new DatagramPacket( buf, buf.length, ); socket.receive(packet); byte[] reply = "done".getBytes( StandardCharsets.UTF_8, ); DatagramPacket out = new DatagramPacket( reply, reply.length, packet.getAddress(), packet.getPort(), ); socket.send(out); } catch (Exception ex) { throw new RuntimeException(ex); } }); receiver.start(); ready.await(); try (DatagramSocket socket = new DatagramSocket()) { byte[] data = "start job".getBytes( StandardCharsets.UTF_8, ); DatagramPacket packet = new DatagramPacket( data, data.length, InetAddress.getByName("127.0.0.1"), port[0], ); socket.send(packet); byte[] answerBuf = new byte[256]; DatagramPacket answer = new DatagramPacket( answerBuf, answerBuf.length, ); socket.receive(answer); System.out.println( new String( answer.getData(), 0, answer.getLength(), StandardCharsets.UTF_8, ), ); } } }

Отправьте "time" и выведите ответ "now" в консоли отправителя.

Обменяйтесь фразами "ask" и "reply" в одном запуске. На экране должна появиться только строка ответа.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить