Clear Datagram Buffer in Java
Asked Answered
K

2

6

So I got this simple udp client/server code from the internet, and it works. However, when I enter something that is shorter than the thing I entered before it, I get the remaining characters left over. For example, if I first enter:

kitty

And then enter:

cat

The second print reads as:

catty

I've been looking at other people with similar problems and most of them seem to be solved by clearing the byte array. However, if I try to implement their answers, it doesn't fix my problem. What do I need to do, and (maybe more importantly) where in the code should it go? Here is the code:

Client:

import java.io.*;
import java.net.*;

class UDPClient
 {
    public static void main(String args[]) throws Exception
    {
       BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
       DatagramSocket clientSocket = new DatagramSocket();
       InetAddress IPAddress = InetAddress.getByName("localhost");
       byte[] sendData = new byte[1024];
       byte[] receiveData = new byte[1024];
       String sentence = inFromUser.readLine();
       sendData = sentence.getBytes();
       DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 20700);
       clientSocket.send(sendPacket);
       DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
       clientSocket.receive(receivePacket);
       String modifiedSentence = new String(receivePacket.getData());
       System.out.println("FROM SERVER:" + modifiedSentence);
       clientSocket.close();
    }
 }

Server:

import java.io.*;
import java.net.*;
import java.util.*;

class UDPServer
 {
    public static void main(String args[]) throws Exception
       {
          DatagramSocket serverSocket = new DatagramSocket(21200);
          byte[] receiveData = new byte[1024];
          byte[] sendData = new byte[1024];
          while(true)
                {
                   DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                   serverSocket.receive(receivePacket);
                   String sentence = new String( receivePacket.getData(), 0, receivePacket.getLength());
                   System.out.println("RECEIVED: " + sentence);
                   InetAddress IPAddress = receivePacket.getAddress();
                   int port = receivePacket.getPort();
                   String capitalizedSentence = sentence.toUpperCase();
                   sendData = capitalizedSentence.getBytes();
                   DatagramPacket sendPacket =  new DatagramPacket(sendData, sendData.length, IPAddress, port);
                   serverSocket.send(sendPacket);
                }
       }
 }
Kurys answered 9/7, 2013 at 13:17 Comment(0)
R
10

You don't need to clear the byte array, but you do need to take some notice of the length of the DatagramPacket after the receive, via the getLength() method; for example:

new String(packet.getData(), packet.getOffset(), packet.getLength());

You're doing that correctly in the server, but not in the client.

You also need to reset the length before calling receive(). Otherwise the DatagramPacket will keep shrinking to the length of the smallest packet received so far.

Refresh answered 9/7, 2013 at 23:54 Comment(3)
DatagramPacket.setLength()?Refresh
@Kurys you reset the length through: receivePacket.setLength(receiveData.getLength())Allman
@Allman You mean receivePacket.setLength(receiveData.length).Refresh
T
0

Greeting from the future (10 years after posted). This post asked a problem I had, so I'll tell you what I did to solve it.

In the code provided, his client closes, so the issue isn't from the client side, it's from the server side. The solution I used was putting

byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];

within the loop. This makes them local variable, so be careful not to skip them on accident. It also probably messes with memory, because it's deleting and re-initializing it every time.

Don't know if it's "best practice", but it worked so it's good for my purposes. If you also have a repeating client, you can also use this method.

Tram answered 25/10, 2023 at 16:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.