Java UDP 数据包丢失。 50%
Java UDP packet loss. 50%
我正在制作在线 java 游戏。现在我正在使用 UDP 数据包。在每秒更新 60 15 次时,我现在有大约 50% 的丢包率。当它托管在我的本地计算机上和托管在我的服务器上时,都会发生这两种情况。我试过发送更少的数据包和更慢地发送它们都没有帮助。提前致谢。
正在发送数据包:
while(true) {
try {
socket = new DatagramSocket();
if(id >= 0) {
data = (PacketID.POS.toString() + tempobj.x + "/" + tempobj.y + "/" + tempobj.getHelth() + "/" + id + "/").getBytes();
}else {
data = (PacketID.POS.toString() + tempobj.x + "/" + tempobj.y + "/" + tempobj.getHelth() + "/" + tempobj.isSheild + "/" + tempobj.name + "/" + tempobj.size + "/" + (int)(tempobj.getVelx()) + "/" + (int)(tempobj.getVely())).getBytes();
}
DatagramPacket packet = new DatagramPacket(data, data.length, ip, port);
if(tempobj.x != lx || tempobj.y != ly || tempobj.helth != lh) {
packetssent++;
System.out.println(packetssent);
lx = tempobj.x;
ly = tempobj.y;
lh = tempobj.helth;
socket.send(packet);
}
Thread.sleep(66);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
接收数据包:
byte[] arr = new byte[40];
DatagramPacket data = new DatagramPacket(arr, arr.length);
while(true) {
socket.receive(data);
String s = new String(data.getData(),0, data.getLength());
if(s.substring(0, 3).equalsIgnoreCase(PacketID.POS.name())) {
String[] split = s.substring(3).split("/");
System.out.println(reciver);
for(int i = 0; i < players.size(); i++) {
if((players.get(i).id - 1) == Integer.parseInt(split[3].trim())) {
players.get(i).x = Integer.parseInt(split[0].trim());
players.get(i).y = Integer.parseInt(split[1].trim());
players.get(i).helth = Integer.parseInt(split[2].trim());
}
}
}
s = null;
}
对于 UDP 数据包丢失,您可能无能为力,但您还没有尝试过。除了...也许...尝试获得更好的端到端网络连接。
数据包丢失通常是由于最拥塞链路上的网络拥塞造成的。除非您拥有并管理这些链接,否则您对此无能为力。
也许您应该改用 TCP。或者更改您的应用程序,使其能够应对 50% 的数据包丢失...
我注意到您的代码存在一个问题。您的发送代码正在创建一个全新的 DatagramSocket
来发送每个 UDP 消息,然后不关闭套接字。这是低效的,并且可能导致资源泄漏问题。 (虽然它不应该导致数据包丢失。)
如果这是 linux 主机,您可以尝试检查是否没有超出任何缓冲区。过去我一直被类似的问题困扰。检查 netstat -s
的输出并检查 udp
部分是否有掉落。
我正在制作在线 java 游戏。现在我正在使用 UDP 数据包。在每秒更新 60 15 次时,我现在有大约 50% 的丢包率。当它托管在我的本地计算机上和托管在我的服务器上时,都会发生这两种情况。我试过发送更少的数据包和更慢地发送它们都没有帮助。提前致谢。
正在发送数据包:
while(true) {
try {
socket = new DatagramSocket();
if(id >= 0) {
data = (PacketID.POS.toString() + tempobj.x + "/" + tempobj.y + "/" + tempobj.getHelth() + "/" + id + "/").getBytes();
}else {
data = (PacketID.POS.toString() + tempobj.x + "/" + tempobj.y + "/" + tempobj.getHelth() + "/" + tempobj.isSheild + "/" + tempobj.name + "/" + tempobj.size + "/" + (int)(tempobj.getVelx()) + "/" + (int)(tempobj.getVely())).getBytes();
}
DatagramPacket packet = new DatagramPacket(data, data.length, ip, port);
if(tempobj.x != lx || tempobj.y != ly || tempobj.helth != lh) {
packetssent++;
System.out.println(packetssent);
lx = tempobj.x;
ly = tempobj.y;
lh = tempobj.helth;
socket.send(packet);
}
Thread.sleep(66);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
接收数据包:
byte[] arr = new byte[40];
DatagramPacket data = new DatagramPacket(arr, arr.length);
while(true) {
socket.receive(data);
String s = new String(data.getData(),0, data.getLength());
if(s.substring(0, 3).equalsIgnoreCase(PacketID.POS.name())) {
String[] split = s.substring(3).split("/");
System.out.println(reciver);
for(int i = 0; i < players.size(); i++) {
if((players.get(i).id - 1) == Integer.parseInt(split[3].trim())) {
players.get(i).x = Integer.parseInt(split[0].trim());
players.get(i).y = Integer.parseInt(split[1].trim());
players.get(i).helth = Integer.parseInt(split[2].trim());
}
}
}
s = null;
}
对于 UDP 数据包丢失,您可能无能为力,但您还没有尝试过。除了...也许...尝试获得更好的端到端网络连接。
数据包丢失通常是由于最拥塞链路上的网络拥塞造成的。除非您拥有并管理这些链接,否则您对此无能为力。
也许您应该改用 TCP。或者更改您的应用程序,使其能够应对 50% 的数据包丢失...
我注意到您的代码存在一个问题。您的发送代码正在创建一个全新的 DatagramSocket
来发送每个 UDP 消息,然后不关闭套接字。这是低效的,并且可能导致资源泄漏问题。 (虽然它不应该导致数据包丢失。)
如果这是 linux 主机,您可以尝试检查是否没有超出任何缓冲区。过去我一直被类似的问题困扰。检查 netstat -s
的输出并检查 udp
部分是否有掉落。