Ответ по UDP в Java
UDP не хранит клиента отдельно: кто прислал пакет,
видно в getAddress и getPort у
DatagramPacket после receive.
Ответ собирают так же: массив байтов и новый
DatagramPacket с тем же хостом и портом
источника.
Приёмник после чтения текста формирует короткий ответ на английском и шлёт его тем же сокетом:
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 = "ack".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);
}
}
}
Текст ответа может зависеть от пришедшего сообщения, но адрес назначения всегда берут из входящего пакета. Отправитель в том же процессе может ждать ответ на своём сокете:
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 = "got it".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 = "hello".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,
),
);
}
}
}
На запрос "check" ответьте текстом
"ok". Адрес отправителя возьмите из
принятого пакета.
На запрос "version" ответьте
"1.0" и выведите ответ на стороне
отправителя в консоль.