Java String Equals not working for UDP server received packet - java

Here are simple UDP client-server classes:
UDPServer:
import java.net.*;
/**
* Source:https://systembash.com/a-simple-java-udp-server-and-udp-client/
*
*/
class UDPServer {
public static void main(String args[]) throws Exception {
DatagramSocket serverSocket = new DatagramSocket(9876);
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());
// Sentence here is not equal "PING" ?
if(sentence.equals("PING")) {
System.out.println("It is PING: " + sentence);
} else {
System.out.println(sentence.getClass());
System.out.println("It is not equal PING. It is <" + sentence + ">");
}
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
String capitalizedSentence = "PONG";
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket
= new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
UDPClient:
import java.net.*;
/**
* Source:
* https://systembash.com/a-simple-java-udp-server-and-udp-client/
*
* #author
*/
class UDPClient {
public static void main(String args[]) throws Exception {
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = "PING";
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
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();
}
}
In the UDPServer there's a check for the response (variable sentence). For some reason the equals doesn't detect the "PING" when it has to. Moreover it outputs the sentence string is "PING", class string.
Why is that ?
The output of the UDPServer is the else:
class java.lang.String
It is not equal PING. It is:<PING>
RECEIVED: PING
If it matters the java version is "1.7.0_91".

getData() gives you a buffer from which you can obtain your data.
Don't use trim() as this could remove characters you actually want to keep (apart from being expensive)
Instead you should use the length of the message
String sentence = new String(receivePacket.getData(), 0, receivePacket.getLength());
This way you will only extract to portion of the buffer with data you want.

The getData method of DatagramPacket returns the underlying buffer, which is the 1024 byte buffer you created earlier. You create a String from this buffer. All bytes not filled in will be 0 (default initialized), so your String will contain a lot of additional zero's. That's why the equals method returns false. You could solve this with the trim method if you're sure the messages sent will not have leading or trailing whitespaces (or at least, none that matter to the rest of the program).

You are not getting true when calling equals because the response is 1024 bytes long. You can trim your response on UDPServer to solve this:
String sentence = new String(receivePacket.getData()).trim();

Related

JAVA UDP Server Can't receive Packet

I have a sample code as below and the socket is bound to IP 10.10.88.11 and port 9876. I tested with the 2 conditions with wireshark as below. Both PCs are in the same subnet.
Send UDP packet from the same pc (10.10.88.11) - UDP Server able to receive
Send UDP packet from another pc ( 10.10.88.10) - UDP Server unable to receive but Wireshark (at 10.10.88.11) able to capture the packets
I have searched the internet but can't find a solution for this. Is there anything i did wrong in creating the InetScoketAddress?
import java.io.*;
import java.net.*;
public class UDPServer {
public static void main(String args[]) throws Exception {
InetSocketAddress address = new InetSocketAddress("10.10.88.11", 9876);
DatagramSocket serverSocket = new DatagramSocket(address);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
System.out.println("Waiting to receive");
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
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);
}
}
}
I believe Wireshark is able to grab packets before they are evaluated by the firewall, meaning that you will detect them but they will never reach the java app. Did you try deactivating your firewall ?

How to properly compare string values received from datagram packets?

I'm making a simple client server program. When the client sends the string "start", I want the server to start executing some code. Right now, I have the client sending a datagram packet with the message "start", the server gets the byte buffer from the packet, turns it into a string, and then compares that string value with the string literal "start". Obviously I'm doing something wrong because my code never enters the for loop of if(sentence.equals(start){ System.out.println("ok");}
My code:
public static void main(String args[]) throws IOException{
byte[] receiveData;
byte[] sendData;
DatagramSocket serverSocket = new DatagramSocket(2014);
while(true){
receiveData = new byte[15];
DatagramPacket frame = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(frame);
InetAddress IPaddress = frame.getAddress();
System.out.println("INET " + IPaddress);
byte[] data;
int port = frame.getPort();
System.out.println("port " + port);
String sentence = new String(frame.getData());
String start = new String("start");
System.out.println("RECEIVED FROM CLIENT: " + sentence);
if(sentence.equals(start)){
System.out.println("ok");
}
}
}
Make the following change.
String sentence = new String(frame.getData(), 0, frame.getLength());

Udp how to get integer from the server?

i shall implement a UDP-based client/server application and im new in the world of Java. The Server implements a simple request-acknowledge protocol upon the UDP protocol. For a received string identifier (command) with optional parameters the server returns a specified result. For example "thread" returns a random integer number between 1 and 5 and length returns a random integer number between 5 and 25.
The questions is did i do the implementation right and how can i fix my problem (length nr is always between 1 and 5). I think my problem is that in the server class the if statements are not checked. Is there some other way to send a comand to a server i tried here to do it with sending strings then trying to check it with if statements?
and thats my code (Server):
public class server {
public static void main(String[] args) throws IOException, InterruptedException {
DatagramSocket skt;
try {
skt = new DatagramSocket(1252);
byte [] buffer = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
skt.receive(request);
String arrayMsg = new String(request.getData());
System.out.println(arrayMsg);
//check if the client asks for threadnr
if(arrayMsg.equals("thread")){
int threadnumber = (int) (Math.random()*5)+1;
String threadnum = Integer.toString(threadnumber);
byte [] b = threadnum.getBytes();
DatagramPacket reply = new DatagramPacket(b, b.length, request.getAddress(), request.getPort());
skt.send(reply);;}
//check if the client asks for lengthnr
else if(arrayMsg.equals("length")){
int lengthnumber = (int) (Math.random()*25)+5;
String lengthnum = Integer.toString(lengthnumber);
byte [] b = lengthnum.getBytes();
DatagramPacket reply = new DatagramPacket(b, b.length,request.getAddress(), request.getPort());
skt.send(reply);}
}}
catch (SocketException e) {
System.out.println("UDP Port 9876 is occupied.");
System.exit(1);
}}}
thats my Client:
public class client {
public static void main(String[] args) throws UnknownHostException, IOException {
DatagramSocket skt = new DatagramSocket();
InetAddress host = InetAddress.getByName("localhost");
int serverSocket = 1252;
byte [] senddata = new byte [1000];
byte [] getdata = new byte[1000];
//thread send request
String th = "thread";
senddata = th.getBytes();
DatagramPacket requestth = new DatagramPacket(senddata, senddata.length, host, serverSocket);
skt.send(requestth);
//thread get reply
DatagramPacket replyth = new DatagramPacket ( getdata, getdata.length);
skt.receive(replyth);
String arrayth = new String(replyth.getData());
int threadnr=Integer.parseInt(arrayth.trim()); //convert thread string to int and trim it (whitespace)
System.out.println("Thread received " + threadnr);
//length send request
String lg = "length";
senddata = lg.getBytes();
DatagramPacket requestlg = new DatagramPacket(senddata, senddata.length, host, serverSocket);
skt.send(requestlg);
//length get reply
DatagramPacket replylg = new DatagramPacket ( getdata, getdata.length);
skt.receive(replylg);
String arraylg = new String(replyth.getData());
int lengthnr=Integer.parseInt(arraylg.trim()); //convert thread string to int and trim it (whitespace)
System.out.println("Length received " + lengthnr);
skt.close();
And all i get is something like this:
Thread received 3
Length received 1
(Length should be between 5 and 25 and in my case its never bigger then 5)
The code parses the response from the first message instead of from the last, so you get the random 1-5. I suggest using better names for the variables and you'll spot the problem quicker.

UDP client and server connection

I am currently writing two java classes (client and server). The client takes an input number form keyboard and sends it to the server. The server then multiplies this number by two and sends it back to the client. The numbers should also be printed to screen along the way, for example if I input the number 3 I should get
"From Client: 3"
"From Server: 6"
They should continuously do this unless a negative number is received by the client, say for example the number -3 is sent to the server and it returns -6.
The code I have for the two classes so far is:
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.util.Scanner;
class Client {
public static void main(String args[]) throws Exception
{
DatagramSocket clientSocket = new DatagramSocket();
System.out.println("Insert number: ");
Scanner s= new Scanner(System.in);
int num = s.nextInt();
byte[] sendData = ByteBuffer.allocate(4).putInt(num).array();
InetAddress IPAddress = InetAddress.getByName("localhost");
int port = 1999;
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length , IPAddress ,1999);
clientSocket.send(sendPacket);
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
byte[] receiveData = new byte[4];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
int numberReceived = ByteBuffer.wrap(receivePacket.getData()).getInt();
System.out.println("FROM SERVER:" + numberReceived);
clientSocket.close();
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;
class Server {
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(1999);
while(true)
{
byte[] receiveData = new byte[4];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
int num = ByteBuffer.wrap(receivePacket.getData()).getInt();
System.out.println("FROM Client:" + num);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
int numtosend = num * 2;
byte[] sendData = ByteBuffer.allocate(4).putInt(numtosend).array();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress,port);
serverSocket.send(sendPacket);
}
}
}
Currently, when I run the program all I get is an output of the number first entered.
Can anyone tell me where I am going wrong?
Many thanks in advance :)
Where you are going wrong is that you haven't finished the program yet.
Your client only reads one number, sends one number, receives one reply.
You need a loop.
You also need to implement the part about stopping on a negative number.

Java TCP and UDP echo in one server

I am trying to build a server which can echo the input from either a TCP or a UDP client.
So far the best I could come up with is this:
import java.net.*;
import java.io.*;
public class EchoServerMultiProtocol {
public static void main(String[] args) throws IOException {
String clientSentence;
String capitalizedSentence;
while (true) {
/*******************************************************************
* * Handle TCP * *
*******************************************************************/
ServerSocket TCP_Socket = new ServerSocket(6789);
Socket connectionSocket = TCP_Socket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
/*******************************************************************
* * Handle UDP * *
*******************************************************************/
DatagramSocket UDP_Socket = new DatagramSocket(9876);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
UDP_Socket.receive(receivePacket);
clientSentence = new String(receivePacket.getData());
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
capitalizedSentence = clientSentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, IPAddress, port);
UDP_Socket.send(sendPacket);
}
}
}
What happens is that if I send a message from the TCP client the program works as expected but from the UDP client nothing happens. I'm not very well versed in client/server communication so any help would be appreciated.
The client codes are below but I doubt they are the source of the problem.
TCP Client
import java.io.*;
import java.net.*;
class EchoClientTCP {
public static void main(String argv[]) throws Exception {
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
System.in));
Socket clientSocket = new Socket("127.0.0.1", 6789);
DataOutputStream outToServer = new DataOutputStream(
clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
}
}
UDP Client
import java.io.*;
import java.net.*;
class EchoClientUDP {
public static void main(String args[]) throws Exception {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("127.0.0.1");
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, 9876);
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();
}
}
Thank you for your help.
Your program blocks waiting for a TCP message, so it never sees any UDP.
You will need, at least, two threads, one for each.
Accept is a blocking call. It never gets to the part of the code with the UDP socket.
Please just make your life easy and use Netty. In a couple of lines of code you have an efficient thread model, support for most common protocols and a great framework to handle messages.

Categories