Java UDP Chat Program: Part of first message gets appended onto second - java

I'm writing a client-server chat program using UDP. If either the client or the server sends a message, and the next message they send is shorter than the previous one they sent, part of the longer message will be put onto the end of the shorter one. This is my first time using UDP and I've no idea what could be causing this, I made a similiar program using TCP and didn't have this issue.
What the client sees:
Client: Hello, how are you?
Server: I'm good thanks, and you?
Client: Great
What the server sees:
Client: Hello, how are you?
Server: I'm good thanks, and you?
Client: Great, how are you?
My server code:
public class ChatServer implements Runnable
{
public static void main(String[] args) throws Exception
{
new Thread(new ChatServer()).start();
}
#Override
public void run()
{
try
{
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DatagramSocket serverSocket = new DatagramSocket(9876);
byte[] receiveData = new byte[65508];
byte[] sendData = new byte[65508];
System.out.println("Enter a username: ");
String serverUsername = inFromUser.readLine();
System.out.println("Send message...");
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String clientSentence = new String(receivePacket.getData());
System.out.println(clientSentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
System.out.print("Me: ");
String serverSentence = serverUsername + ": " + inFromUser.readLine();
sendData = serverSentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
catch (IOException ex)
{
Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
My client code:
public class ChatClient
{
public static void main(String[] args) throws Exception
{
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
try (DatagramSocket clientSocket = new DatagramSocket())
{
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[65508];
byte[] receiveData = new byte[65508];
System.out.println("Enter a username: ");
String clientUsername = inFromUser.readLine();
System.out.println("Send message...");
while(true)
{
System.out.print("Me: ");
String clientSentence = clientUsername + ": " + inFromUser.readLine();
sendData = clientSentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String serverSentence = new String(receivePacket.getData());
System.out.println(serverSentence);
}
}
catch(Exception e)
{
e.getMessage();
}
}
}

Receive Packet is initially null terminated.
It gets filled in with the network data.
You need to tell the string how many bytes to read or zero out receiveData after each construction of clientSentence. Using the length of the packet is the correct way to approach this.
Change:
String clientSentence = new String(receivePacket.getData());
To:
String clientSentence = new String(receivePacket.getData() ,0 , receivePacket.getLength());

Related

Server doesn't detect second client connecting

The problem i have is that when i open a second client, the server doesn't seem to detect that a second client was opened. With the first time the client being opened it works fine and the server detects that a client has been connected.
Server:
public class Server {
Socket previousSocket = null;
private static int port = 9001;
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("[SERVER] Server successfully launched on port: " + port);
DatagramSocket UDPSocket = new DatagramSocket(9002);
Socket previousSocket = null;
while (true) {
Socket newSocket = serverSocket.accept();
System.out.println("new client connected");
if (previousSocket == null) {
previousSocket = newSocket;
System.out.println("1 st client");
} else {
System.out.println("2 nd client");
previousSocket = null;
}
byte[] data = new byte[500];
DatagramPacket received = new DatagramPacket(data, data.length);
while(true) {
UDPSocket.receive(received);
String receivedData = new String(received.getData());
System.out.println(receivedData);
}
}
}
}
Client:
public ChatClient() throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 9001);
Scanner scanner = new Scanner(System.in);
DatagramSocket UDPSocket = new DatagramSocket();
while(scanner.hasNextLine()) {
String message = scanner.nextLine();
InetAddress ip = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length, ip, 9002);
UDPSocket.send(packet);
}
}
The following loop will never end, that's the reason for your problem
while(true) {
UDPSocket.receive(received);
String receivedData = new String(received.getData());
System.out.println(receivedData);
}

Java Socket Programming (Client,Bridge,Server)

The task is to
(1) Send message from Client to Server via Bridge
(2) Send back the message in UPPER CASE from server to client via Bridge
(1) is done
I am have problem with sending the message back to the client
Here are the classes:
UDPCLIENT
import java.io.*;
import java.net.*;
class UDPClient
{
public static void main(String args[]) throws Exception
{
//getting input from the user and sending to Bridge
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, 4000);
clientSocket.send(sendPacket);
//Getting data from the Bridge
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("C: FROM SERVER:" + modifiedSentence);
clientSocket.close();
}
}
UDPSERVER
import java.io.*;
import java.net.*;
class UDPServer
{
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(5000);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true)
{
//receiveing data from the bridge
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
System.out.println("S:RECEIVED: " + sentence);
InetAddress IPAddress = InetAddress.getByName("localhost");
// Sending data to the bridge
int port = 4000;
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
Bridge
import java.io.*;
import java.net.*;
/**
* Write a description of class Bridge here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Bridge
{
public static void main(String args[]) throws Exception{
DatagramSocket bridgeSocket1 = new DatagramSocket(4000);
DatagramSocket bridgeSocket2 = new DatagramSocket();
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
DatagramPacket receivePacket;
DatagramPacket sendPacket;
InetAddress IPAddress = InetAddress.getByName("localhost");
while(true){
//Receiveing data from the UDPClient
receivePacket = new DatagramPacket(receiveData, receiveData.length);
bridgeSocket1.receive(receivePacket);
//Sending data to UDPServer
String sentence = new String(receivePacket.getData());
System.out.println("B: Data Received:" + sentence);
int port = 5000;
sendData = sentence.getBytes();
sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
bridgeSocket2.send(sendPacket);
// Receiving Data from the UDPServer
receivePacket = new DatagramPacket(receiveData,receiveData.length);
bridgeSocket1.receive(receivePacket);
String capitalizedSentence = new String(receivePacket.getData());
System.out.println("Capitalized Sentence in the Bridge Class: " + capitalizedSentence);
//Sending data to the UDPClient
sendData = capitalizedSentence.getBytes();
sendPacket = new DatagramPacket(sendData,sendData.length,IPAddress,5000);
bridgeSocket2.send(sendPacket);
}
}
}
You are sending the response from the server back to the server because you are using port 5000 as the destination port. But the server is running on 5000, not your client. You have to assign your client to a port as well and send the message received from the server back to the client on the defined port.
For now your sequence looks like this:
(C) ---> 4000
---> 5000
4000 <---
---> 5000
4000 <---
---> 5000
4000 <---
---> 5000
4000 <---
[...]
But it should look like this:
(C) ---> 4000
---> 5000
4000 <---
4500 <---
(assuming your client is listening on port 4500)

Java - creating threads for different tasks

public class server implements Runnable {
private static final int initialize_server_Port = 8080 ;
private static final int store_server_Port = 8181;
private static final int search_server_Port = 8282;
private static String tname ;
private static InetAddress address ;
protected static Hashtable<String , InetAddress> file_location = new Hashtable<String ,InetAddress>();
server(String tname){
this.tname = tname ;
}
public void run(){
try{
if("storeRecords".equals(tname))
storeRecord();}catch(IOException e ){
System.out.println("error: unable to create store socket");
}
try{
if("searchRecords".equals(tname))
searchRecord();}catch(IOException e){
System.out.println(e);
}
// if("search".equals(tname))
// searchRecord();
}
public void start(){
Thread thread = new Thread(this , tname );
thread.start();
}
public static void storeRecord() throws IOException{
System.out.println("store out");
DatagramSocket serverSocket = new DatagramSocket(store_server_Port);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true){
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String file = new String( receivePacket.getData());
file = file.trim();
System.out.println("RECEIVED: " + file);
InetAddress IPAddress = receivePacket.getAddress();
address = IPAddress;
int port = receivePacket.getPort();
System.out.println(file);
file_location.put(file , IPAddress);
String confirmation= "Successfully uploaded";
sendData = confirmation.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
public static void searchRecord() throws IOException{
System.out.println("search out");
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
DatagramSocket serverSocket = new DatagramSocket(search_server_Port);
while(true){
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String file = new String( receivePacket.getData());
file = file.trim();
System.out.println("RECEIVED: " + file);
InetAddress IPAddress = receivePacket.getAddress();
address = IPAddress;
int port = receivePacket.getPort();
boolean found = file_location.containsKey(file);
if(found == true ){
InetAddress query = file_location.get(file);
String confirmation= "found";
sendData = confirmation.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);}
else if (found != true){
String confirmation= "404";
sendData = confirmation.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
protected static String server_IP ;
public static void main(String[] args) throws IOException {
server storeThread = new server("storeRecords"); //**************
storeThread.start();
server searchThread = new server("searchRecords");
searchThread.start(); //*********************************
// PrintWriter pw = null ;
//Socket socket = null ;
try {
InetAddress iAddress = InetAddress.getLocalHost();
server_IP = iAddress.getHostAddress();
System.out.println("Server IP address : " +server_IP);
} catch (UnknownHostException e) {
}
DatagramSocket serverSocket = new DatagramSocket(initialize_server_Port);
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 confirmation= "Successfully initialized";
sendData = confirmation.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
So right now the output is
search out
search out
what im trying to do is create three threads, one thread running the main, 2nd thread running storeRecord which should printout Store out
and 3rd running searchRecord ,
what am i doing wrong here?
In your code, tname is a static variable, hence, shared by all instances of server. It is assigned twice in two calls to the constructor. Making it an instance variable (i.e., removing the static) should do what you want.

Multiple Clients in UDP server

I wrote this code to recive data from a client via socket
import java.io.*;
import java.net.*;
class UDPServer
{
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(12890);
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);
}
}
}
But if I try to launch another Client it don't work , look like if the server is blocked. How can I change the code to let the server communicating with more then one client
You are looking for a concurrent server. A concurrent server basically creates a child process for each client. Here is a basic way to do in java http://www.how2java.com/2012/05/how-to-create-concurrent-server-using.html

parsing a string into two part with Split method

I was parsing a string into 2 parts partitioned by the 1st appearance of the '&' character. For example: if the string is 555&hello &world the partitions will be 555 and hello &world. I used following code:
String[] numberAndMessage=currentMessage.split("(\\&)",2);
System.out.println(numberAndMessage[1]+storedMessage.message+"end");
So, with input: 555&hello &world
The output I expected was: hello &worldend
But instead it gave: hello &world
Maybe any problem in the ending character of 2nd partition.
But what is the problem?
The code:
UDPServer.java:
import java.net.*;
public class UDPServer extends Thread{
public void run(){
try{
DatagramSocket serverSocket = new DatagramSocket(9999);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String currentMessage = new String( receivePacket.getData());
System.out.println("RECEIVED: " + currentMessage);
String[] numberAndMessage=currentMessage.split("(\\&)", 2);
System.out.println("noAndMessage[0]="+numberAndMessage[0]+";noAndMessage[1]="+numberAndMessage[1]);
System.out.println("numberAndMessage[1]= "+numberAndMessage[1]+"end");
}
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public static void main(String args[]) throws Exception
{
UDPServer server=new UDPServer();
server.start();
}
}
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, 9999);
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();
}
}
Input at UDPClient.java:
555&hello world
Output at UDPServer.java:
RECEIVED: 555&hello world
noAndMessage[0]=555;noAndMessage[1]=hello world
numberAndMessage[1]= hello world
i dont know about storedMessage.message .but following code works good for you expecting output.
String currentMessage="555&hello &world";
String[] numberAndMessage=currentMessage.split("(\\&)",2);
System.out.println(numberAndMessage[1]+"end");
here you will get OUtPUT:
hello &worldend
Try this
public class Test {
public static void main(String[] args) {
String currentMessage = "555&hello &world";
String[] numberAndMessage = currentMessage.split("(\\&)", 2);
System.out.println(numberAndMessage[1] + "end");
}
}
output
hello &worldend
for your full code I got this following result
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPServer extends Thread{
public void run(){
try{
DatagramSocket serverSocket = new DatagramSocket(9999);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
String a = "555&hello world";
receiveData = a.getBytes();
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
//serverSocket.receive(receivePacket);
String currentMessage = new String( receivePacket.getData());
System.out.println("RECEIVED: " + currentMessage);
String[] numberAndMessage=currentMessage.split("(\\&)", 2);
System.out.println("noAndMessage[0]="+numberAndMessage[0]+";noAndMessage[1]="+numberAndMessage[1]);
System.out.println("numberAndMessage[1]= "+numberAndMessage[1]+"end");
}
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public static void main(String args[]) throws Exception
{
UDPServer server=new UDPServer();
server.start();
}
}
Output is
RECEIVED: 555&hello world
noAndMessage[0]=555;noAndMessage[1]=hello world
numberAndMessage[1]= hello worldend

Categories

Resources