Search code examples
javaudppacket

UDP response packet contents getting cut short


I'm trying to create a simple Java UDP Client-Server program. The server/host waits for an appropriate request from the client before doing something. Everything seems to be working fine but the reply from the host to the client is always truncated for some reason.

I assume it has something to do with the the length of "Bob" as all responses from the host is shortened to 3. I tried messing around with setLength() and the buffer size but can't seem to figure it out...

Client.java:

public class Client {

    public static void main(String[] args) throws Exception {
        
        //Use Java's built-in DatagramSocket and DatagramPacket to implement UDP
        DatagramSocket socket = new DatagramSocket(); //Create socket object to send data
        socket.setSoTimeout(5000); //Throw an exception if no data received within 5000ms
        
        //Create scanner to grab user input
        Scanner input = new Scanner(System.in);
        System.out.print("Please enter a message to send to Alice: ");
        String bobInput = input.nextLine(); //Storing user input
        input.close(); //Close scanner to prevent memory leaks
        
        byte[] buffer = new byte[65535];
        
        //Create packet containing message
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("localhost"), 1500);
        packet.setData(bobInput.getBytes());
        socket.send(packet); //Send message to host
        
        socket.receive(packet);
        
        System.out.println("Received from Alice: " + new String(packet.getData(),0,packet.getLength()));
        
        socket.close();
    }
}

Host.java

public class Host {

    public static void main(String[] args) throws Exception {
        
        //Use Java's built-in DatagramSocket and DatagramPacket to implement UDP
        DatagramSocket socket = new DatagramSocket(1500); //Create a socket to listen at port 1500
        byte[] buf = new byte[65535]; //Byte array to wrap
        
        System.out.println("Parameters successfully read. Listening on port 1500...");

        //While-loop to keep host running until terminated
        while (true) {
          DatagramPacket packet = new DatagramPacket(buf, buf.length); //Create a packet to receive message
          socket.receive(packet); //Receive the packet
          
          //If Alice receives a packet with the message "Bob"
          if(new String(packet.getData(),0,packet.getLength()).equals("Bob")) {
              System.out.println("Bob has sent a connection request.");
              
              String test = "Hello Bob!";
              packet.setData(test.getBytes());
              
              System.out.println("Text sent: " + new String(packet.getData(),0,packet.getLength()));
              
          }
        }
    }
}

Console output for client:

Please enter a message to send to Alice: Bob

Received from Alice: Hel

Console output for host:

Parameters successfully read. Listening on port 1500...

Bob has sent a connection request.

Text sent: Hello Bob!

It's my first time working with UDP so I apologize if its some basic mistake that I made.


Solution

  • In the client, you create a packet of length 3 (because the content is 'Bob'). You use the same packet for a receive, which per the doc will then truncate the received data to the packet length.

    The DatagramPacket class does not appear to distinguish 'length of underlying buffer' from 'length of data in buffer'.

    Best to use separate packet structures; the send packet just needs to contain 'Bob'; the receive packet needs to be large enough for the maximum expected response.

    (Debugging hint: figuring this out starts with noticing that it's unlikely to be mere coincidence that the lengths of the transmitted message and of the truncated received message are identical).