我需要使用 UDP 广播进行对等发现。
环境:
docker-desktop
使用单节点 Kubernetes 集群
我的代码如下所示:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainApp {
public static void main(String[] args) throws ExecutionException, InterruptedException {
int inPort = Integer.parseInt(System.getenv("IN_PORT"));
int outPort = Integer.parseInt(System.getenv("OUT_PORT"));
String name = System.getenv("NAME");
Client client = new Client(name, outPort);
Server server = new Server(name, inPort);
ExecutorService service = Executors.newFixedThreadPool(2);
service.submit(client);
service.submit(server).get();
}
static class Client implements Runnable {
final String name;
final int port;
Client(String name, int port) {
this.name = name;
this.port = port;
}
@Override
public void run() {
System.out.println(name + " client started, port = " + port);
try (DatagramSocket socket = new DatagramSocket()) {
socket.setBroadcast(true);
while (!Thread.currentThread().isInterrupted()) {
byte[] buffer = (name + ": hi").getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length,
InetAddress.getByName("255.255.255.255"), port);
socket.send(packet);
Thread.sleep(1000);
System.out.println("packet sent");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
static class Server implements Runnable {
final String name;
final int port;
Server(String name, int port) {
this.name = name;
this.port = port;
}
@Override
public void run() {
System.out.println(name + " server started, port = " + port);
try (DatagramSocket socket = new DatagramSocket(port)) {
byte[] buf = new byte[256];
while (!Thread.currentThread().isInterrupted()) {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData(), 0, packet.getLength());
System.out.println(String.format(name + " received '%s' from %s:%d", received,
packet.getAddress().toString(),
packet.getPort()));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
Kubernetes pod 设置:
对于peer-1
:
spec:
containers:
- name: p2p
image: p2p:1.0-SNAPSHOT
env:
- name: NAME
value: "peer-1"
- name: IN_PORT
value: "9996"
- name: OUT_PORT
value: "9997"
对于peer-2
:
spec:
containers:
- name: p2p-2
image: p2p:1.0-SNAPSHOT
env:
- name: NAME
value: "peer-2"
- name: IN_PORT
value: "9997"
- name: OUT_PORT
value: "9996"
为了简单起见,我使用了不同的输入/输出端口。实际上应该是同一个端口,例如:9999
我看到每个 pod 都有一个唯一的 IP 地址
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
p2p-deployment-2-59bb89f9d6-ghclv 1/1 Running 0 2m26s 10.1.0.38 docker-desktop <none> <none>
p2p-deployment-567bb5bd77-5cnsl 1/1 Running 0 2m29s 10.1.0.37 docker-desktop <none> <none>
日志来自peer-1
:
peer-1 received 'peer-2: hi' from /10.1.0.1:57565
日志来自peer-2
:
peer-2 received 'peer-1: hi' from /10.1.0.1:44777
问题:为什么从而不是peer-1
接收UDP数据包?10.1.0.1
10.1.0.37
如果我登录到peer-2
容器:kubectl exec -it p2p-deployment-2-59bb89f9d6-ghclv -- /bin/bash
然后
socat - UDP-DATAGRAM:255.255.255.255:9996,broadcast
test
test
...
在peer-1
我看到的日志中peer-1 received 'test' from /10.1.0.1:43144
。再次为什么网络地址10.1.0.1
而不是10.1.0.37
.
你能告诉我我做错了什么吗?
注意:当使用同一端口发送/接收 UDP 数据包时,某些对等方可以接收到来自其自身 IP 地址的数据包。换句话说,对等点只能发现自己的 IP 地址,但总是获取10.1.0.1
从其他对等点/pod 接收到的数据包