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);
Related
I am working on a problem that will create a TCP server and client using sockets. For the client code, my objective is to repeatedly prompt the user to enter a sentence S, send the sentence S to the server, receive the response from the server, and display the message received and the round trip time expressed in milliseconds. On the server, my objective is to create a TCP server socket, wait for a client to connect, receive a message, display it with the IP address and port # of the client, capitalize the message, display the message, and echo back the "capitalized" message.
I am trying to use a while (!(input.equals("done"){ ...do something }, however, whatever I do is getting stuck in an infinite loop. I hope its something simple I am just overlooking, but I don't see it.
TCPServer.java
import java.net.*;
import java.io.*;
public class myFirstTCPServer {
public static void main(String[] args) throws IOException {
int servPort = 4999;
ServerSocket Sy = new ServerSocket(servPort);
Socket servSocket = Sy.accept();
InputStreamReader in = new InputStreamReader(servSocket.getInputStream());
BufferedReader bf = new BufferedReader(in);
String str = bf.readLine();
while (!(str.equals("done"))){
System.out.println("client connected");
InetAddress address = InetAddress.getLocalHost();
String ip = address.getHostAddress();
System.out.println("IP: " + ip);
System.out.println("Port: " + servPort);
System.out.println("Message from client: " + str.toUpperCase());
PrintWriter pr = new PrintWriter(servSocket.getOutputStream());
pr.println(str);
pr.flush();
}
servSocket.close();
}
}
TCPClient.java
import java.net.*;
import java.io.*;
import java.util.Scanner;
public class myFirstTCPClient {
public static void main(String[] args) throws IOException {
String S;
Scanner input = new Scanner(System.in);
System.out.println("Enter a sentence");
S = input.nextLine();
Socket clntSocket = new Socket(InetAddress.getLocalHost(), 4999);
while (!(S.equals("done"))){
double sent = System.nanoTime();
PrintWriter pr = new PrintWriter(clntSocket.getOutputStream());
pr.println(S);
pr.flush();
InputStreamReader in = new InputStreamReader(clntSocket.getInputStream());
BufferedReader bf = new BufferedReader(in);
String str = bf.readLine();
System.out.println("Message from server: " + str);
double received = System.nanoTime();
double total = received - sent;
System.out.println("Round Trip Time: " + (total/1000000.0));
}
clntSocket.close();
}
}
you need to move reader into the while loop. Because this is where server waits for reading clients input.
public class myFirstTCPServer {
public static void main(String[] args) throws IOException {
int servPort = 4999;
ServerSocket Sy = new ServerSocket(servPort);
Socket servSocket = Sy.accept();
System.out.println("client connected");
InputStreamReader in = new InputStreamReader(servSocket.getInputStream());
BufferedReader bf = new BufferedReader(in);
String str ="";
while (true)){
str = bf.readLine();
if(str.equals("done")) break;
InetAddress address = servSocket.getInetAddress();
String ip = address.getHostAddress();
System.out.println("IP: " + ip);
System.out.println("Port: " + servPort);
System.out.println("Message from client: " + str);
PrintWriter pr = new PrintWriter(servSocket.getOutputStream());
pr.println(str.toUpperCase());
pr.flush();
}
servSocket.close();
}
}
And then change client side:
public class myFirstTCPClient {
public static void main(String[] args) throws IOException {
String S="";
Scanner input = new Scanner(System.in);
// you need to provide your server ip/domain
// InetAddress.getLocalHost() , still works but only works when
// your client is in the same machine.
Socket clntSocket = new Socket("127.0.0.1", 4999);
while (!(S.equals("done"))){
System.out.println("Enter a sentence");
S = input.nextLine();
double sent = System.nanoTime();
PrintWriter pr = new PrintWriter(clntSocket.getOutputStream());
pr.println(S);
pr.flush();
InputStreamReader in = new InputStreamReader(clntSocket.getInputStream());
BufferedReader bf = new BufferedReader(in);
String str = bf.readLine();
System.out.println("Message from server: " + str);
double received = System.nanoTime();
double total = received - sent;
System.out.println("Round Trip Time: " + (total/1000000.0));
}
clntSocket.close();
}
}
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);
Details d = new Details(5425, "Vosu Mittal/CN");
ByteArrayOutputStream byteoutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectoutputstream = new ObjectOutputStream(byteoutputStream);
objectoutputstream.writeObject(d);
sendData = byteoutputStream.toByteArray();
DatagramPacket sendpacket = new DatagramPacket(sendData, sendData.length, internetAddress, port);
socket.send(sendpacket);
Server Side Code is
receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
System.out.print("Connected to Server");
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
int packetsize = receivePacket.getLength();
byte[] bytecount = receivePacket.getData();
ByteArrayInputStream byteinputStream = new ByteArrayInputStream(bytecount);
ObjectInputStream objectinputStream = new ObjectInputStream(byteinputStream);
Details d = (Details)objectinputStream.readObject();
String data = new String(d.toString());
System.out.println("\t"+ data+ "\tIP Address is = "+ IPAddress+ "\tPort Address is ="+ port+ "\tByte Count is = "+ packetsize );
String reply = "Thank you for the message";
My class is defined as Follows with Serializable Interface
int id;
String name;
private void showDetails(){
System.out.println("Id:"+id);
System.out.println("Name:"+name);
}
Still, I am not able to get them on the client side, rectify the code if required?
I am trying to understand UDP connectionless client - server pair. I got some code in the Book Computer Networking: A Top Down Approach.
The Programs are as follows:-
UDPServer.java:
import java.io.*;
import java.net.*;
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());
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);
}
}
}
UDPClient.java
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, 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 given code we have fixed the port no for the Server ,i.e., 9876.
I am curious to know that how to fix the port for Client, as we did for Server in the given java program, so that message can be returned to Client on the Specific Port.
For example, if the
client will send a UDP message to the server, the server will start and run on port number 9876 and return the original message to the client on port 9877. Please help.
You don't need a fixed port at the client, any more than the client needs a fixed IP address. Your own code should already work correctly. However there are other issues:
String sentence = new String( receivePacket.getData());
Wrong. It should be String sentence = new String( receivePacket.getData(), receivePacket.getOffset(), 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);
This code will send the reply back to from whence the request came. An easier way is to use the same DatagramPacket for both receive and send, and just change the data.
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.