Compare receive packet with string UDP protocol - java

is some way to compare
String sentence = new String(receivePacket.getData());
with some string ?
I tried compare with
Arrays.equals(sentence.getBytes(),new String("Hello").getBytes();)
return false ...
I tried
if(sentence.equals("Hello"))
doesnt work too.
I think something is wrong with receivedPacket but data in packet are the same
like
'Hello' vs 'Hello'
System.out.println(sentence.getBytes()+ " vs " + "Hello".getBytes());
output -
[B#4f0e921d vs [B#459ad677

new String(packet.getData());
The problem is here. You're ignoring the length. It should be:
new String(packet.getData(), packet.getOffset(), packet.getLength());

Related

UDP datagram Socket Programming with server in JAVA and Client in C++

Below is the code for client server communication using UDP datagram protocol with server in JAVA and Client in cpp.
The task of the server is to read the data received from the client on its port and then unpack the string.
Now using String Builder we want to write that in the output file.
The problem which we are facing is that the output in the file is
javac UDPServer.java | On terminal2 Running gcc -g client.cpp -o client
java UDPServer | On terminal2 Running ./client
56,abcde^#,orange1
However the correct output should be
56,abcde,orange1
Also, pls check for closing of the file objects such as fo.close() and fw.close(), we have used finally block; Is that a good idea to close file descriptor objects?? Or shall we need to use some other techniques to close the file descriptor objects??
Below is the code for server:
import java.io.*;
import java.net.*;
import java.util.regex.*;
class UDPServer {
public static void main(String args[]) throws Exception
{
FileOutputStream fo = new FileOutputStream("OUTFILE.txt",true);
PrintWriter pw = new PrintWriter(fo);
StringBuilder sb= new StringBuilder();
DatagramSocket serverSocket = new DatagramSocket(11111);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
try{
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
System.out.println("Got packet form address:" +IPAddress);
String capitalizedSentence = sentence.toUpperCase();
if (receivePacket != null && receivePacket.getLength() != 0) {
String result = new String(receivePacket.getData());
result = result.trim(); // remove leading and trailing whitespaces...
String match_pattern="(\\d+)(a.*)(y.*)";
//create a pattern object
Pattern regexp_patternobject= Pattern.compile(match_pattern);
//create a matcher object
Matcher m_obj= regexp_patternobject.matcher(result);
if (m_obj.find()){
System.out.println("Found Value: " +m_obj.group(0) );
System.out.println("Found Value: " +m_obj.group(1) );
System.out.println("Found Value: " +m_obj.group(2) );
System.out.println("Found Value: " +m_obj.group(3) );
sb.append(m_obj.group(1));
sb.append(',');
sb.append(m_obj.group(2));
sb.append(',');
sb.append(m_obj.group(3));
sb.append('\n');
System.out.println("StringBuilderValue: " +sb);
pw.write(sb.toString());
}
else
{
System.out.println("Matching Pattern Not Found");
}
pw.write(sb.toString());
}
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
finally{
pw.close();
fo.close();
}
}
}
Your C program is sending a stream of bytes representing the contents of a struct ssi_dump_nmsdata_type instance.
typedef struct {
char rssi;
unsigned char bssid[6];
char ssid[16];
} ssi_dump_nmsdata_type;
The bssid field is a 6-byte array of unsigned char, and in the instance you show the value is abcde in the first 5 bytes with the last byte being 0x00. In C that would be taken as the end-of-string character and not printed. Strings in Java are not null-terminated so that character is being printed.
You need to change the code in Java that unpacks the struct to better cope with the possibility of one or more trailing null bytes (0x00) in the bssid and ssid fields. Regular expressions are a bad idea here, and what you've got so far will fail as soon as you receive a BSSID that doesn't start with a or an SSID that doesn't start with y.
You should first split up the buffer based on character count (1, 6 and 16 bytes) and then remove any trailing null bytes from BSSID and SSID.
However you should be aware that what you are doing glosses over some important and subtle details. When you do (in Java)
String result = new String(receivePacket.getData());
The received data is being decoded from a byte stream to a Java Unicode character string using the default encoding. If the stream contains non-ASCII byte values (outside the range 0x00-0x7f) you may get unexpected results. Explaining all the ramifications in detail is beyond the scope of what SO is intended for.
You should investigate and learn about the difference between a byte stream (what you C program is sending) and a Java String. You should be splitting up the fields of the struct from the byte stream first, as bytes, before converting them to Java String instances. The buffer classes in java.nio are intended for just this purpose, so I recommend you follow some tutorials on "Java NIO Buffers".
UDPServer.java has no problem .
the problem comes from cpp client.
I recommend you to fix like this:
bssid length: from 6 to 5.

Sending objects using sockets - JAVA

So I am creating an application using sockets. And I have the client who sends a message and it passes to the server using writeObject(new String("Name|Message"));.
And I read the message in the server using readObject();
I am trying to pass this string object to an array. But I get [Ljava.lang.String;#6bb9ae1a.
Here is what I am trying:
ObjectInputStream saida = new ObjectInputStream(client.getInputStream());
String[] read = saida.readObject().toString().split("|");
System.out.println(read);
I tried also to make variables for each split:
String readm = read[1];
String readn = read[0];
But it returns me "" as the name and "A" as the message (?)
Ow, and the socket is working, because if I do (String) saida.readObject(); it returns me the normal string.
use like that :
saida.readObject().toString().split("\\|");
and then
String readm = read[1];
String readn = read[0];
Because pipe symbol is the special character and splitting special chars is different. And you cannot use systemoutprintln to print the string array.

Sending Message via DatagramChannel

I am sending a message via a DatagramChannel as follows:
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
String request_message = "request";
buf.put(request_message.getBytes());
buf.flip();
int bytesSent = udpserver.send(buf, successor_port_1); // udpserver is a DatagramChannel
I then read the message on the server:
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
String message = new String(buf.array(), Charset.forName("UTF-8"));
System.out.println(message); //print message for testing purposes
if (message == "request"){
//code here does not get executed
}
The problem is, my code doesn't enter the "if" statement even though message = "request" which also seems to be confirmed by my print statement.
Any help would be appreciated!
The reason for this is that Strings in java need to be compared with .equals, so your test should be:
if (message.equals("request")){
This is because, in Java, == tests whether two object are the same instance (it tests reference equality - do both the references point to the same memory) rather than equal.
You can carry out a quick test:
System.out.println("request" == new String("request"));
Output:
false
For more information read this SO answer.

How Can I found out what is length of recieved message on serial port?

InputStream inputFromPort;
try {
inputFromPort = serial.getInputStream(); //SerialPort
b=new byte[20];
inputFromPort.read(b);
reading=new String(b,"UTF-8");
System.out.println(reading.length());
System.out.println("new message: " + reading);
inputFromPort.close();
serial.close();
}
RESULT: new message: Hello, world! -> which is OK
six boxes symbols ->(which I can't copy here)I know that they appear 'cause
length of b is larger then "Hello,world!",it would be great if somehow I know size of recieved message so I can initialize byte array b on that size
Check the return value of inputFromPort.read(b);:
int readLength = inputFromPort.read(b);
Then you have to create your string with only the bytes received, that is the part of the byte array that was actually written by the call to read():
String reading = new String(b, 0, readLength, "UTF-8");
This way you won't have "boxes symbols" after the the "Hello, World!"

Server/client in java and c/objective - Encoding issues

I'm trying to write simple code for server/client.
The server (in java) wait for string from client:
ServerSocket ss = new ServerSocket(4001);
Socket s = ss.accept() ;
DataInputStream dataStreamIn = new DataInputStream(s.getInputStream()) ;
byte buffer[] = new byte[100];
dataStreamIn.read(buffer);
if((new String(buffer)).equals("1"))
System.out.print("yes");//never printed
the client (objective-c) send string to server:
uint8_t buffer[1000] ={0};
sprintf((char*)buffer,"%s", "1");
NSInteger wrote = [self.networkStreamOut
write:buffer
maxLength:(uint8_t)strlen((char *)buffer)];
The problem is the buffer on server is indeed "1" BUT when I'm trying to compare with .equals() it return false!
EDIT:
When I'm tring to add to server this line:
System.out.println(Integer.valueOf(new String(buffer))) ;
I'm getting this error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "1
You should explicitly state what encoding you expect your incoming data to be in, on both the client and server side. This is especially important to do when communicating between different platforms/languages.
But, of course, that's not what your problem is - your string is getting created with a bunch of non-printing characters because you allocated it with the entire byte array:
byte[] buffer = new byte[100];
new String(buffer);
Presumably the buffer is not completely filled after you read data into it, and the defaulted zero values in it are getting converted in your string into non-printing characters. You can validate this by printing the length of the string you created, you will find it to be greater than 1.
You have two remedies - either trim() the String before comparing its value, or keep track of the number of actual bytes read and create a new byte array of the correct length (before creating your String).

Categories