gpt4 book ai didi

java - Android可以发送udp但不能接收

转载 作者:行者123 更新时间:2023-11-29 07:37:38 27 4
gpt4 key购买 nike

我编写了一个基本的 udp 客户端服务器,其中一个 android 向服务器发送消息,然后服务器将其转发给其余客户端。

问题是,传入的 udp 消息到达服务器并且服务器将它们中继回去,但它们永远不会到达其余设备。

真正令人惊奇的是,如果我将服务器用作回显服务器(即仅中继到发件人),那么一切正常。所有客户端和服务器套接字都使用相同的端口 2706

服务器代码

while (true) {
DatagramPacket packetToReceive = new DatagramPacket(new byte[2048], 2048);
try {
listenerSocket.receive(packetToReceive);
InetAddress senderAddress = packetToReceive.getAddress();
relayedBytes += packetToReceive.getLength();

if (!connectedClients.contains(senderAddress)) {
connectedClients.add(senderAddress);
}

for (InetAddress addr : connectedClients) {
// commenting this line will make it an echo server
if (!addr.equals(senderAddress))
{
//The following actually prints the ips of the android
//devices so it knows where to send

System.out.println(senderAddress.getHostAddress().toString() +
" to " + addr.getHostAddress().toString());
byte[] data = packetToReceive.getData();
packetToReceive.setData(data, 0, packetToReceive.getLength());
packetToReceive.setAddress(addr);
listenerSocket.send(packetToReceive);
}
}
} catch (IOException) {
e.printStackTrace();
}
}

android 发送器逻辑:

mainSocket=new DatagramSocket(homePort);

//targetAddressString is the public IP of server
target = InetAddress.getByName(targetAddressString);
while (true) {
byte[] data = getdata();
if (data == null)
continue;
DatagramPacket packet = new DatagramPacket(data, data.length, target, targetPort);

mainSocket.send(packet);
}

同时在其他线程上,接收者只是等待相同的 udp 套接字:

while (true) {
Log.d("Player", "Waiting for data");
DatagramPacket packet = new DatagramPacket(new byte[2048], 2048);
try {
mainSocket.receive(packet);
Log.d("Player", "packet received");
//do something with the packet
} catch (IOException e) {
e.printStackTrace();
}
}

它永远不会比等待数据更进一步,因为它会阻塞直到它收到数据包

此外,我还可以在 wifi 和移动数据图标中看到它从未收到任何数据,但数据发送始终打开并且在服务器上看到收到

**编辑:-回声服务器**

while (true) {
DatagramPacket receivedPacket = new DatagramPacket(new byte[2048], 2048);
try {
listenerSocket.receive(receivedPacket);
InetAddress senderAddress = receivedPacket.getAddress();
if (!connectedClients.contains(senderAddress)) {
connectedClients.add(senderAddress);
}

for (InetAddress addr : connectedClients) {
byte[] data = receivedPacket.getData();
DatagramPacket sendPacket= new DatagramPacket(data, 0, receivedPacket.getLength(), addr, receivedPacket.getPort());
listenerSocket.send(sendPacket);
}
} catch (IOException e) {
// ...
}
}

基本上,它应该将消息转发给曾经发送过任何数据的每个客户端,但不知何故它只将其发送给其原始发件人,其余客户端会错过它。代码在和我作对

最佳答案

这就是你想出来的NAT穿越问题。

这里有一些提示:

  1. 服务器可以硬编码为监听端口 2706。但它不应该对接收到的数据包的源端口有任何假设。从您的代码来看,您似乎从未尝试调用 setPort。因此,即使 NAT 没有以不同方式映射您的端口号,我也不确定您的原始代码是如何设置任何目标端口的。但我认为您是根据自己的答案和更新后的代码解决的。

  2. 不要在客户端套接字上硬编码客户端端口。在套接字上选择端口“0”(或不设置),让操作系统为您选择第一个可用端口。如果您在同一个 NAT 后面有多个客户端,此行为将允许更快的客户端重启、多个设备在同一个 NAT 后面,以及其他好处。

关于java - Android可以发送udp但不能接收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33715497/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com