I have to create a peer to peer chat program in java using UDP for my networking class. The purpose of the program is to simulate a conversation between bots, by reading from a text file and sending random lines. Basically, I have a program with a client class and a server class. I run the program twice, the client from the first program sends to the server of the second program, and the client of the second program sends to the server of the first program.
I also have to implement 20% packet loss and if a packet is “lost” then the client has to resend it.
So the way that I am attempting to handle the packet loss is : I have two boolean fields in the Client class “did_I_Receive_The_Packet” and “should_I_Re_Send”. In the server class I choose a random number between 1-10, if the number is 1 or 2 then that means the packet was lost and I set the didIReceicePacket boolean in the client to false. If that boolean is true, then the client sends packets with a random line from the file, if it is false, then the client sends a packet with a string, “$”. In the server class, if a packet has the “$”, then the client boolean shouldIResend is set to true. In the client class if that boolean is true, then the client is supposed to resend the previous packet.
I'm using thread.sleep() so get the programs to send every 5 seconds so that I'm not being bombared by messages. I'm not sure if that is the correct way to do it or if there is a better way.
Currently, when I run the program twice, they are able to send messages to each other, but the packet loss and resending part isn’t working correctly. When the packets are “lost” i’m getting the system.out message that I created for that part, but the resending a lost packet part doesn’t seem to be working.
Also, when the programs are sending lines from the text file, sometimes the lines come out messed up. My text file contains 10 lines, "ten, nine, eight,..."and so on, on seperate lines. For example, instead of nine, it prints ninen, or twoee, instead of two.
I would greatly appreciate any help or advice on how to fix these issues. Thanks!
Here is my code thus far.
import java.io.*; import java.net.*; import java.util.*; import javax.swing.JOptionPane; public class P2pchat { public static void main(String[] args) throws Exception { Server myServer = new Server(); Client myClient = new Client(); myServer.start(); JOptionPane.showMessageDialog (null,"Click ok to start the server" ); myClient.start(); } } import java.io.*; import java.net.*; import java.util.*; import javax.swing.JOptionPane; public class Client extends Thread { private String sentence; private byte[] sendData = new byte[1024]; private DatagramSocket clientSocket; private InetAddress IPAddress; private DatagramPacket sendPacket; private String destPort; private List<String> randomGG; private static boolean did_I_Receive_The_Packet = true; private static boolean should_I_Re_Send = false; @Override public void run() { destPort = JOptionPane.showInputDialog (null, "Enter Port of Destination: "); int port = Integer.parseInt(destPort); try { read(); clientSocket = new DatagramSocket(); while(true) { Thread.sleep(5*1000); if(!should_I_Re_Send)//There is no need to resend the previous packet { if(!did_I_Receive_The_Packet) //i have not received the packet, i must tell the other client's server to resend { IPAddress = InetAddress.getByName("localhost"); String resendPLZ = "$"; sendData = resendPLZ.getBytes(); sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); clientSocket.send(sendPacket); } else if(did_I_Receive_The_Packet)//send a new packet with a random line from le file { IPAddress = InetAddress.getByName("localhost"); sentence = getLine(); sendData = sentence.getBytes(); sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); clientSocket.send(sendPacket); System.out.println("FROM USER1: " + sentence); } } else if(should_I_Re_Send) //I must resend the previous packet or all will be lost { IPAddress = InetAddress.getByName("localhost"); sendData = sentence.getBytes(); sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); clientSocket.send(sendPacket); System.out.println("FROM USER1: Resending previous packet " + sentence); } } } catch(Exception e) { System.out.println("There was an error with the Client"); } } public void read() throws IOException { FileReader file = new FileReader("lol.txt"); BufferedReader reader = new BufferedReader(file); String line = reader.readLine(); List<String> lines = new ArrayList<>(); while (line != null) { lines.add(line); line = reader.readLine(); } randomGG = lines; reader.close(); } public String getLine() { Random r = new Random(); String randomLine = randomGG.get(r.nextInt(randomGG.size())); return randomLine; } public static void setDid_I_Receive_The_Packet(boolean s) { did_I_Receive_The_Packet = s; } public static void setShould_I_Re_Send(boolean rs) { should_I_Re_Send = rs; } } import java.io.*; import java.net.*; import java.util.*; import javax.swing.JOptionPane; public class Server extends Thread { private DatagramSocket serverSocket; private byte[] receiveData; private DatagramPacket receivePacket; private String sentence; private String servPort; private static boolean packetStatus; private String temp; @Override public void run() { try { servPort = JOptionPane.showInputDialog (null, "Enter the port for this application: "); int port = Integer.parseInt(servPort); serverSocket = new DatagramSocket(port); receiveData = new byte[1024]; while(true) { Thread.sleep(5*1000); receivePacket = new DatagramPacket(receiveData, receiveData.length); serverSocket.receive(receivePacket); temp = new String(receivePacket.getData()); if(temp.equals("$")) //if our packet has only an "$" in it, that is the other client letting us know it did not receive our previous packet and to resend { temp = ""; Client.setShould_I_Re_Send(true); } else if(!temp.equals("$")) //the packet doesn't have an $ meaning it is a regular packet from le client { Client.setShould_I_Re_Send(false); int rNum = theLossOfPacketsIsReal(); if(rNum == 1 || rNum == 2) { //the incoming packet has been lost!!! //i must tell my client that i did not receive a packet from the other peers client System.out.println("FROM USER2: packet was lost"); temp = ""; Client.setDid_I_Receive_The_Packet(false); //tell the my client that no you did not receive the packet } else { Client.setDid_I_Receive_The_Packet(true); //tell my client that i received the packet sentence = temp; System.out.println("FROM USER2: " + sentence); } } } } catch(Exception e) { System.out.println("There was an error with the Server"); } } public int theLossOfPacketsIsReal() //chooses a random number between 1-10 { Random randoom = new Random(); int num = randoom.nextInt(10) + 1; return num; } public static boolean isPacketLost() { return packetStatus; } public static void setPacketStatus(boolean s) { packetStatus = s; } }
Here is sample output from when I ran the programs
program#1
run:
FROM USER1: six
FROM USER2: one
FROM USER1: six
FROM USER2: seven
FROM USER1: eight
FROM USER2: seven
FROM USER1: two
FROM USER2: packet was lost
FROM USER2: eight
FROM USER1: seven
FROM USER2: tenht
FROM USER1: six
FROM USER2: packet was lost
FROM USER2: twoht
FROM USER1: nine
FROM USER2: three
FROM USER1: three
FROM USER2: $hree
FROM USER1: one
FROM USER2: $hree
FROM USER1: two
FROM USER2: tenee
program#2
run:
FROM USER2: six
FROM USER1: one
FROM USER2: six
FROM USER1: seven
FROM USER2: eight
FROM USER1: seven
FROM USER2: twoht
FROM USER1: eight
FROM USER2: $woht
FROM USER1: eight
FROM USER2: seven
FROM USER1: ten
FROM USER2: sixen
FROM USER1: one
FROM USER2: $ixen
FROM USER1: two
FROM USER2: ninen
FROM USER1: three
FROM USER2: packet was lost
FROM USER2: packet was lost
FROM USER2: twoee
FROM USER1: ten