Search code examples
javanetwork-programmingudpgame-developmentpacket

Java UDP packet loss. 50%


I am making an online java game. Right now I am using UDP packets. I have about a 50% packet drop rate right now at updating 60 15 times a second. This both happen when it's being hosted on my local machine and hosted on my server. I have tried sending fewer packets and sending them slower neither have helped. Thanks in advance.

Sending packets:

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();
            }
        }

receiving packets:

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;
      }

Solution

  • There is probably nothing you can do about UDP packet loss that you haven't already tried. Except ... maybe ... try and get a better end-to-end network connection.

    Packet loss typically happens as a result of network congestion on the most congested links. Unless you own and manage those links, there is nothing you can do about it.

    Maybe you should be using TCP instead. Or changing your application so that it can cope with 50% packet loss ...


    There is one problem I noticed with your code. Your sending code is creating a brand new DatagramSocket to send each UDP message, and then not closing the socket. That's inefficient, and could lead to resource leak problems. (It shouldn't cause packet loss though.)