Server response blank for some reason? - java

Have a homework to create client code to send a string split into 2 variables over UDP. Server receives and confirms by sending back the two split variables back to front.
For some reason my response is blank when I run it and not sure why.
can anyone help please?
When I try doing it with integers on another code it works but when I try do strings nothing comes back.
Client code:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class UDPClient
{
public static void main (String[] args) throws Exception
{
DatagramSocket client = new DatagramSocket();
InetAddress IPAd = InetAddress.getByName("localhost");
byte [] sendData1 = new byte[1024];
byte [] sendData2 = new byte[1024];
byte [] receiveData = new byte [1024];
String input = "";
Scanner in = new Scanner (System.in);
System.out.println("Enter word: ");
input = in.nextLine();
String [] splitWord = input.split("");
int length = splitWord.length;
int evenSplit = 0;
int oddSplit = 0;
String firstHalf = "";
String secondHalf = "";
if (length%2==0)
{
evenSplit = length / 2;
for (int i=0; i<evenSplit; i++)
firstHalf += splitWord[i];
for (int i=evenSplit; i<length;i++)
secondHalf += splitWord[i];
}
else{
oddSplit = (length+1)/2;
for (int i=0; i<oddSplit;i++)
firstHalf += splitWord[i];
for (int i=oddSplit; i<length;i++)
secondHalf += splitWord[i];
}
sendData1 = firstHalf.getBytes();
sendData2 = secondHalf.getBytes();
DatagramPacket sendPacket1 = new DatagramPacket (sendData1,
sendData1.length, IPAd, 2000);
DatagramPacket sendPacket2 = new DatagramPacket (sendData2,
sendData2.length, IPAd, 2000);
client.send(sendPacket1);
client.send(sendPacket2);
DatagramPacket receivePacket = new DatagramPacket (receiveData,
receiveData.length);
String serverReply = new String (receivePacket.getData());
System.out.println ("From server: " + serverReply);
client.close();
}
}
Server code:
import java.io.*;
import java.net.*;
public class UDPServer
{
public static void main (String [] args) throws Exception
{
DatagramSocket server = new DatagramSocket (2000);
byte [] receiveData1 = new byte[1024];
byte [] receiveData2 = new byte[1024];
byte [] sendData = new byte [1024];
while (true)
{
DatagramPacket receivePacket1 = new DatagramPacket
(receiveData1, receiveData1.length);
server.receive(receivePacket1);
DatagramPacket receivePacket2 = new DatagramPacket
(receiveData2, receiveData2.length);
server.receive(receivePacket2);
String firstHalfWord = new String (receivePacket1.getData());
String secondHalfWord = new String (receivePacket2.getData());
InetAddress IPAd = receivePacket1.getAddress();
int port = receivePacket1.getPort();
String response = secondHalfWord + firstHalfWord;
sendData = response.getBytes();
DatagramPacket sendPacket = new DatagramPacket (sendData,
sendData.length, IPAd, port);
server.send(sendPacket);
}
}
}
If I type hello it is mean to reply with lohel (hel + lo back to front)
it simply comes back with "From server:" without any string response.

Before the line String serverReply = new String(receivePacket.getData()); you need to say client.receive(receivePacket);

Related

Datagram Packet FTP application

I write a FTP application using UDP Datagram Protocol , and I need the client side read from file 100 character and send it in 5 parts , 20 characters in each part , when I run my program I get this error :
Exception in thread "main" java.lang.IllegalArgumentException: illegal length or offset. I want the server get each line in five parts but sort it accordingly.
this is my code :
import java.net.*;
import java.io.*;
public class FTPClient
{
public static void main(String[] args)
{
final int SIZE=100;
DatagramSocket skt= null;
DatagramPacket pkt = null;
BufferedReader read= null;
int port = 3131;
try
{
skt=new DatagramSocket(2121);
read= new BufferedReader(new FileReader("input.txt"));
String line = read.readLine();
byte[] lineByte = new byte[SIZE];
lineByte = line.getBytes();
InetAddress add = InetAddress.getByName("localhost");
for(int i=0;i<100;i+=20)
{
pkt = new DatagramPacket(lineByte,i,20,add,port);
skt.send(pkt);
}
}
catch(IOException e)
{
System.out.println(e.getMessage()); }
finally
{
skt.close();
// read.close();
}
}
}
Your code with comments at problem areas. If you still have problems resolving the issues after reading my comments, just add a comment and I will explain more
public static void main(String[] args) {
final int SIZE = 100;
DatagramSocket skt = null;
DatagramPacket pkt = null;
BufferedReader read = null;
int port = 3131;
try {
skt = new DatagramSocket(2121);
read = new BufferedReader(new FileReader("input.txt"));
String line = read.readLine(); // how long is the line?
byte[] lineByte = new byte[SIZE]; // this is a redundant assignment
lineByte = line.getBytes(); // now the length of the lineBytes is "unknown"
InetAddress add = InetAddress.getByName("localhost");
for (int i = 0; i < 100; i += 20) { // you should check the length of lineBytes instead of 100
pkt = new DatagramPacket(lineByte, i, 20, add, port);
skt.send(pkt);
}
}
catch (IOException e) {
System.out.println(e.getMessage());
}
finally {
skt.close();
// read.close();
}
}

How to get the file name from an RRQ datagramPacket?

Im working on a TFTP server. Basing on the image the max length of my packets is 516 bytes (2+2+512).
I'm trying to take the original length from the client datagrampacket(in this case sends 13 bytes in a RRQ packet), instead im getting the server datagrampacket length (516 bytes) where i save the client datagrampacket.
I need that for extract the filename, i did that but the string content is "filename + nullBytes", those null bytes come from the server datagrampacket.
This is the code where im stuck:
public static short RRQ = 1;
enter code here
public void dataMetod() throws IOException{
byte[] packet = new byte[516];
//socket with listening port 5000
DatagramSocket datagramSocket = new DatagramSocket(5000);
//while receive packets
while (true) {
DatagramPacket datagramPacket = new DatagramPacket(packet,packet.length);
datagramSocket.receive(datagramPacket);
System.out.println("server: new packet!!:");
//create a byte[] with the "received packet length"(that's not true)
byte[] inData = new byte[datagramPacket.getLength()];
inData = datagramPacket.getData();
System.out.println("length: "+inData.length);
byte code;
code = inData[1];
System.out.println(code);
//check if its an RRQ packet
if (code == RRQ) {
System.out.println("server: RRQ PACKET!!");
String fileName = this.getFileName(inData);
System.out.println(fileName);
}
public String getFileName(byte[] inData) {
byte[] aux = new byte[inData.length - 7];
for (int i = 0; i < aux.length; i++) {
aux[i] = inData[i + 2];
}
return new String(aux);
}
http://i.stack.imgur.com/6dTH6.png
Try this:
public String getFileName(byte[] inData) {
final int maxLen = inData.length;
final StringBuilder sb = new StringBuilder();
int i = 2;
byte b;
while ( (i < maxLen) && (b = inData[i]) != 0 ) {
final int v = ((int)b) & 0xff;
sb.append( (char) v );
i++;
}
return sb.toString();
}
Instead of getting the original length of the received packet(to search the file name through the array), we could do that by adding "\n" at fileName String in client class, then use BufferedReader which will detect "\n" and save the fileName.
Code:
public String getFileName(byte[] inData) throws IOException {
//get a sub-array, from index[2] (beacuse we dont want opCode) to inData length
byte[] b =Arrays.copyOfRange(inData, 2, inData.length);
InputStream is = new ByteArrayInputStream(b);
BufferedReader bf = new BufferedReader(new InputStreamReader(is));
//We read a word that will be saved when "\n" is found.
//(adding "\n" previously to the fileName String in client class)
String filename = bf.readLine();
bf.close();
is.close();
System.out.println("server: filename is: "+filename.length()+" bytes");
return filename;
}

Multicast a file to a group of users

I have a problem to send a file to a group of users. Users could receive the file was sent from server but the file would not be saved if it is less than 8kb.
Here is the code:
MulticastSocketServer
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class MulticastSocketServer{
public static void main(String[] args) {
String fileName;
String address = "235.0.0.1";
int port = 2222;
Scanner in = new Scanner(System.in);
System.out.print("Please enter file name : ");
fileName = in.next();
try (DatagramSocket serverSocket = new DatagramSocket()) {
InetAddress addr = InetAddress.getByName(address);
BufferedReader br = new BufferedReader(new FileReader(fileName + ".txt"));
DatagramPacket fn = new DatagramPacket(fileName.getBytes(),fileName.getBytes().length, addr, port);
serverSocket.send(fn);
DatagramPacket msgPacket = null;
String txt = "";
while((txt = br.readLine())!=null){
msgPacket = new DatagramPacket(txt.getBytes(),txt.getBytes().length, addr, port);
serverSocket.send(msgPacket);
System.out.println(txt);
}
}catch (IOException ex) {ex.printStackTrace();}
}
}
MulticastSocketClient
import java.io.*;
import java.net.*;
public class MulticastSocketClient {
public static void main(String[] args) throws UnknownHostException {
int port = 2222;
String address = "235.0.0.1";
InetAddress addr = InetAddress.getByName(address);
byte[] buf = new byte[64];
byte[] buf2 = null ;
try (MulticastSocket clientSocket = new MulticastSocket(port)){
clientSocket.joinGroup(addr);
DatagramPacket fn = new DatagramPacket(buf, buf.length);
clientSocket.receive(fn);
String name = new String(buf, 0, buf.length);
String fileName = name.trim();
try(PrintWriter pw = new PrintWriter(new FileWriter(fileName+"2.txt"))){
while (true) {
buf2 = new byte [1024];
DatagramPacket msgPacket = new DatagramPacket(buf2, buf2.length);
clientSocket.receive(msgPacket);
String msg = new String(buf2,0,buf2.length);
String txt = msg.trim();
pw.println(txt);
System.out.println(txt);
}
}catch(FileNotFoundException ex){ex.printStackTrace();}
} catch (IOException ex) {ex.printStackTrace();}
}
}
You're never exiting the while (true) loop, because you don't have any mechanism for transmitting end of stream, so you're never closing the PrintWriter, so it isn't flushing its final buffer, so any file < 4096 chars won't get flushed at all, so it will be zero length.
However your code has much worse problems that this. You are assuming:
the filename fits into 1024 characters
every line of the input file fits into 1024 bytes
the filename is received first
all the content packets are received
all the content packets are received in order
all the content packets are received exactly once
the length of every datagram is 1024
the data is text, not binary, and can be converted losslessly to a String
You're using UDP. That means that most of these assumptions are invalid.

Data wont send through DatagramSocket

For some reason, the data in my datagramsocket wont send. Im trying to make a simple chatclient.
Here is how my chat client is going to work:
The person enters the username
They enter the IP
It connects
They send messages
Here is my code:
Client 1 (Sends and recieves):
// Server Info
public static int serverPort = 8743;
public static String serverName = "ServerName";
// Functions for the server
#SuppressWarnings("resource")
public static void main(String args[]) throws Exception {
DatagramSocket serverSocket = new DatagramSocket();
byte[] receiveData = new byte[1024];
System.out.println("You are now the host.");
boolean enteredDetails = false;
String username = null;
String ipAddress = null;
System.out.print("Enter your username: ");
Scanner userInput = new Scanner(System.in);
if (userInput.hasNext()) {
username = userInput.next();
}
System.out.print("Enter the IP: ");
if (userInput.hasNext()) {
ipAddress = userInput.next();
enteredDetails = true;
}
while (true) {
Scanner message = new Scanner(System.in);
if (message.hasNextLine()) {
String messageFormat = username + ": " + message.nextLine();
byte[] sendData = messageFormat.getBytes();
InetAddress IPAddress = InetAddress.getByName(ipAddress);
DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, InetAddress.getByName(ipAddress), 9876);
serverSocket.send(sendPacket);
System.out.println(messageFormat);
}
// Recieve text
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
System.out.println(sentence);
}
}
For the second client (recieves only):
#SuppressWarnings("resource")
public static void main(String args[]) throws Exception {
DatagramSocket serverSocket = new DatagramSocket();
byte[] receiveData = new byte[1024];
boolean enteredDetails = false;
String username = null;
String ipAddress = null;
System.out.print("Enter your username: ");
Scanner userInput = new Scanner(System.in);
if (userInput.hasNext()) {
username = userInput.next();
}
System.out.print("Enter the IP: ");
if (userInput.hasNext()) {
ipAddress = userInput.next();
enteredDetails = true;
}
while (true) {
// Recieve text
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
System.out.println(sentence);
}
}
Client 1:
DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, InetAddress.getByName(ipAddress), 9876);
This client is sending to port 9876.
Client 2:
DatagramSocket serverSocket = new DatagramSocket();
There's no way this client is ever going to receive anything, as it is receiving on an unknown port which is different every time you run it. It should be:
DatagramSocket serverSocket = new DatagramSocket(9876);

Finding GCD, Socket Programming in Java

I have written the following two codes for finding GCD of two numbers. (via UDP Server)
GCD_UDPClient.java
import java.io.*;
import java.net.*;
class GCD_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];
System.out.print("First Number: ");
String input1 = InFromUser.readLine();
System.out.print("Second Number: ");
String input2 = InFromUser.readLine();
String Input = input1 + ' ' +input2;
SendData = Input.getBytes();
DatagramPacket SendPacket = new DatagramPacket(SendData, SendData.length, IPAddress, 9836);
ClientSocket.send(SendPacket);
DatagramPacket ReceivePacket = new DatagramPacket(ReceiveData, ReceiveData.length);
ClientSocket.receive(ReceivePacket);
String ModifiedInput = new String(ReceivePacket.getData());
System.out.println("GCD From Server: " +ModifiedInput);
ClientSocket.close();
}
}
GCD_UDPServer.java
import java.io.*;
import java.net.*;
#SuppressWarnings("unused")
class GCD_UDPServer
{
#SuppressWarnings("resource")
public static void main(String args[]) throws Exception
{
DatagramSocket ServerSocket = new DatagramSocket(9836);
byte[] ReceiveData = new byte[1024];
byte[] SendData = new byte[1024];
while(true)
{
DatagramPacket ReceivePacket = new DatagramPacket(ReceiveData, ReceiveData.length);
ServerSocket.receive(ReceivePacket);
String input = new String(ReceivePacket.getData());
InetAddress IPAddress = ReceivePacket.getAddress();
int port = ReceivePacket.getPort();
int ar[] = new int[2],i=0;
for (String Number: input.split(" ", 2))
{
ar[i] = Integer.parseInt(Number);
i=i+1;
}
String Answer = Integer.toString(calculategcd(ar[0],ar[1]));
SendData = Answer.getBytes();
DatagramPacket SendPacket = new DatagramPacket(SendData, SendData.length, IPAddress, port);
ServerSocket.send(SendPacket);
}
}
public static int calculategcd(int a, int b)
{
if(b%a == 0)
return a;
else
return calculategcd(b%a,a);
}
}
ClientSocket.receive(ReceivePacket); doesn't seem to work properly, any clues why? Full codes are posted only for clarity.
Output given by the above codes:
First Number: 5
Second Number: 25
[waits indefinitely]
Output Required:
First Number: 5
Second Number: 25
GCD From Server: 5
You are sending 1024 bytes to the server, and you placed your data in a String like "5 25". When you receive the data you split it and you will have "5", and "25" followed by the other bytes in your buffer. Either you use Number.trim() to throw away those extra bytes, or you send a smaller packet (if that is possible).
I had a test , the GCD_UDPServer.java have a exception like
Exception in thread "main" java.lang.NumberFormatException: For input string: "12"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at GCD_UDPServer.main(GCD_UDPServer.java:24)
and simply change line 24
ar[i] = Integer.parseInt(Number);
to
ar[i] = Integer.parseInt(Number.trim());
and it works properly.

Categories

Resources