Received UDP message has incorrect length - java

I am recieving a UDP message from a DatagramSocket and am trying to parse the message like this:
this.broadSock.receive(recvPacket);
// Decode response
byte[] response = recvPacket.getData();
String strResp = new String(response);
String[] splitResp = strResp.split("\\s+");
log.debug("The String: " + strResp + " has the length " + strResp.length());
InetAddress lobbyAdress = InetAddress.getByName(splitResp[0].substring(1));
String portStr = splitResp[1];
int lobbyPort = Integer.parseInt(portStr);
I am getting the following Exception:
java.lang.NumberFormatException: For input string: "8080"
So there is something wrong with the received String as the debug output gives me:
The String: /192.168.0.11 8080 has the length 256
Anybody an idea why this is happening?

The length is provided, and you're ignoring it. It should be:
String strResp = new String(packet.getData(), packet.getOffset(), packet.getLength());
String[] splitResp = strResp.split("\\s+");
log.debug("The response: " + strResp + " has the length " + packet.length());

The fact that strResp.length is 256 is a symptom of a bug in your code. It should be 18 instead.
You are constructing strResp using the entire length of the DatagramPacket buffer without regard to how many bytes are actually in that buffer. DatagramPacket.getData() does not return a new byte[] for just the bytes received. It returns the entire buffer.
That means strResp ends up with 238 extra characters after the port number, and they are not whitespace characters that would be stripped off by split("\\s+"), so splitResp[1], and thus strPort, ends up with more than just digit characters in it, thus violating the requirements of Integer.parseInt().
You need to take the DatagramPacket length into account when constructing strResp:
byte[] response = recvPacket.getData();
int responseOffset = recvPacket.getOffset();
int responseLength = recvPacket.getLength();
String strResp = new String(response, responseOffset, responseLength);

Related

How to read data coming from TCP Socket separated by a specific delimeter

I need to read Bytes of data from a Server using Socket connection over TCP. The data is in the form of a Byte Stream delimited by delimited by one or more octets with a value of 255 (0xFF)
I am using BufferedInputSream to read the data. A part of my code is below:
String messageString = "";
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
byte[] bytes = new byte[16 * 1024];
System.out.println("Receiving Bytes");
while(true)
{
bytesRead = in.read(bytes);
messageString += new String(bytes,0,bytesRead);
if (<SOME CONDITION TO KNOW THAT DELIMITER IS RECEIVED>)
{
System.out.println("Message Received: " + messageString);
//Proceed to work with the message
messageString = "";
}
}
I need the IF condition so that I know that I have received one data packet and start processing the same.
I don't know the length of the message that I am going to receive neither I have the information to the length in the incoming message.
Please help me read this type of byte data.
Any help is truly appreciated.
If your delimiter is 255 you can just check the data you just read for that value:
bytesRead = in.read(bytes);
int index= bytes.indexOf(255);
if (index<0)
{
messageString += new String(bytes,0,bytesRead);
}
else //<SOME CONDITION TO KNOW THAT DELIMITER IS RECEIVED>)
{
messageString += new String(bytes,0,index);
System.out.println("Message Received: " + messageString);
//Proceed to work with the message
messageString = "";
}

Java String to array of bytes wrong conversion

I have a client server Java code and the client is reading in a string "input" and it should then decrypt it, the decryption function needs an array of bytes, so I need to convert the string to array of bytes, which is done using "getBytes()" function, however it seems that this function is modifying the String! How can I convert the string into an array of bytes without changing its content.
String input = inputline.substring(66, inputline.length());
System.out.println("Read message +"+input+"+");
byte[] bx = input.getBytes(Charset.forName("UTF-8"));
System.out.println("Read message +"+bx.toString()+"+");
System.out.println("Read message +"+bx+"+");
the output of the code snippet is as follows:
Read message +[B#161cd475+
Read message +[B#4e25154f+
Read message +[B#4e25154f+
Try writing a for loop to print out the results. I believe Java is spitting out a random memory value for your output.
(int i = 0; s <= bx.length;i++)
{
System.out.println("Read message +" + bx[i].toString() + "+");
System.out.println("Read message +" + bx + "+");
}
Not sure if my for loop is correct, but it may give you something to work with. I hope this helps.
This should work for you. I needed to make a String object from the byte array...
String inputline = "[B#161cd475";
String input = inputline.substring(0, inputline.length());
System.out.println("Read message +"+input+"+");
byte[] bx = input.getBytes();
// Convert to String object
String tmp = new String(bx);
// Print statements.
System.out.println("Read message +" + tmp + "+");

Exception when parsing int from String after it was sent with Datagram

I'm starting to feel real stupid - and hopefully this question's got a simple answer.
I'm trying to send the coordinates of a Point object over UDP. The sending works great:
public void send(Point p) throws IOException {
String data = Integer.toString(p.x) + " " + Integer.toString(p.y);
InetAddress IPAddress = InetAddress.getByName(this.remoteHost);
byte[] sendData = new byte[1024];
sendData = data.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, this.remotePort);
socket.send(sendPacket);
}
And I can receive the data on the other end:
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
this.socket.receive(receivePacket);
As you might see I'm sending the String "X Y", for example "329 456". I now need to parse those values to integers, so I can use them on the other end:
String[] parts = data.split(" ");
int x = Integer.parseInt(new String(parts[0]));
int y = Integer.parseInt(new String(parts[1]));
But this gives me a NumberFormatException on the y integer ("For input string: '456'"). Why? Is there anything I'm missing here? I've been thinking about he actual encoding of the characters send - could that be the reason why Integer won't understand the value?
Thank you for any help.
I guess you don't take packet length into account when converting packet data to String.
You should do it as follows:
String data = new String(receivePacket.getData(), 0, receivePacket.getLength());
Also, it would be better to specify character encoding explicitly when sending and receiving the message, to prevent issues when machines have different default encodings:
sendData = data.getBytes("UTF-8");
...
String data = new String(receivePacket.getData(), 0, receivePacket.getLength(), "UTF-8");
Are you reading data in this way?
String data = new String(receivePacket.getData(), 0, receivePacket.getLength());

Reading Datagram Packet Incorrectly

I am reading a DatagramPacket into a byte[] as such:
byte[] buffer = new byte[4 + size];
DatagramPacket request = new DatagramPacket(buffer, 4 + size);
receiver_Socket.receive(request);
I then print out the contents of the byte[].
String string = new String(buffer);
System.out.println(string);
The info that should be in the DatagramPacket is an int and 15 characters. size has been set to 15. However, when I print out the byte[] I just get 4 random symbols.
I printed out the byte[] right before I sent it and the output was: a random symbol, followed by the correct 15 characters... I am certain I am sending over 19 bytes as I also checked this value prior to sending the DatagramPacket.
Would anyone know what is going on here?
Thank you.

byte[] to String conversion with proper truncation in Java

I have a byte array of size 200 that has data received with socket.receive(). Let's say the packet data is "hello".
int size = 200;
DatagramPacket packet = new DatagramPacket(new byte[size], size);
socket.receive(packet);
byte[] byte1 = packet.getData();
I tried to convert the byte array into string, and the string length is 200 even though it prints out only 'hello' string.
String result = new String(byte1); // .toString();
System.out.println(result.length()); --> 200
System.out.println(result); ---> hello
How can I truncate the String to contain only "hello" when converting it from byte[]?
ADDED
Based on malchow's answer, this solved my issue:
int packetLength = packet.getLength();
byte[] byte1 = packet.getData();
String result = new String(byte1);
return result.substring(0, packetLength);
maybe you should try to check the length of the data received AFTER receiving it:
http://docs.oracle.com/javase/1.5.0/docs/api/java/net/DatagramPacket.html#getLength%28%29
this should be 4 (after the call to socket.receive())
If the extra bites are all empty/whitespace, trim() should do it.

Categories

Resources