Ответ по UDP в Kotlin
UDP не хранит «клиента» отдельно: кто прислал пакет,
видно в полях address и port у
DatagramPacket после receive.
Ответ собирают так же - массив байтов и новый
DatagramPacket с тем же хостом и портом
источника.
Приёмник после чтения текста формирует короткий ответ на английском и шлёт его тем же сокетом:
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
import java.util.concurrent.CountDownLatch
fun main() {
val ready = CountDownLatch(1)
var port = 0
Thread {
DatagramSocket(0).use { socket ->
port = socket.localPort
ready.countDown()
val buf = ByteArray(256)
val packet = DatagramPacket(buf, buf.size)
socket.receive(packet)
val reply = "ack".toByteArray()
val out = DatagramPacket(
reply,
reply.size,
packet.address,
packet.port,
)
socket.send(out)
}
}.start()
ready.await()
DatagramSocket().use { socket ->
val data = "ping".toByteArray()
val packet = DatagramPacket(
data,
data.size,
InetAddress.getByName("127.0.0.1"),
port,
)
socket.send(packet)
}
}
Текст ответа может зависеть от пришедшего сообщения, но адрес назначения всегда берут из входящего пакета. Отправитель в том же процессе может ждать ответ на своём сокете:
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
import java.util.concurrent.CountDownLatch
fun main() {
val ready = CountDownLatch(1)
var port = 0
Thread {
DatagramSocket(0).use { socket ->
port = socket.localPort
ready.countDown()
val buf = ByteArray(256)
val packet = DatagramPacket(buf, buf.size)
socket.receive(packet)
val reply = "got it".toByteArray()
val out = DatagramPacket(
reply,
reply.size,
packet.address,
packet.port,
)
socket.send(out)
}
}.start()
ready.await()
DatagramSocket().use { socket ->
val data = "hello".toByteArray()
val packet = DatagramPacket(
data,
data.size,
InetAddress.getByName("127.0.0.1"),
port,
)
socket.send(packet)
val buf = ByteArray(256)
val answer = DatagramPacket(buf, buf.size)
socket.receive(answer)
println(
String(answer.data, 0, answer.length),
)
}
}
На запрос "check" ответьте текстом
"ok". Адрес отправителя возьмите из
принятого пакета.
На запрос "version" ответьте
"1.0" и выведите ответ на стороне
отправителя в консоль.