My problem is when the garbler print the bits array it print the PINGMESSAGE as well and I don't want that! Can anyone let me know how to fix this problem!!
And also how to make the input allow the space for example if the user typed: Hello Man! It only print Hello! How to fix that please
Here is the code:
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
public class Client {
public static final String MESSAGETONODE = "message to node";
public static final String CHECK = "checking message";
public static final String PING = "PING message";
public static final String CHECKMESSAGE = "Are you alive?";
public static final String PINGMESSAGE = "I'm okay";
public static final String DEATHNOTE = "Death note";
public static final String BIRTHCERT = "Birth cert";
public static ArrayList<Node> linkNode = new ArrayList<Node>();
private static int sourceNode;
static int destPort;
static int destNode;
private int neighborCounts;
private static int sourcePort;
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
private static BlockingQueue<QueueMessage> blockingQueue;
private static ArrayList<BlockingQueue<QueueMessage>> PINGQueue;
private static NetworkLayer networkLayer;
public Client(int nodeID, String itcFile) throws IOException {
blockingQueue = new ArrayBlockingQueue<>(100);
PINGQueue = new ArrayList<>();
assignFromFile(itcFile);
networkLayer = new NetworkLayer(itcFile, nodeID, linkNode);
neighborCounts = networkLayer.getNeighborsCount();
for (int i = 0; i < neighborCounts; ++i) PINGQueue.add(new ArrayBlockingQueue<>(100));
// networkLayer.displayRoutingTable();
System.out.println(nodeID + " " + itcFile);
sourceNode = nodeID;
// Gets the port number of the node you initially set
for (Node n : linkNode) {
if (n.getNodeID() == nodeID)
sourcePort = n.getPortNumber();
}
startServer(sourcePort);
startSender();
messagePrompt(reader, blockingQueue);
for (int i = 0; i < neighborCounts; ++i)
networkLayer.checkNeighbors(blockingQueue, PINGQueue.get(i), i);
}
public void messagePrompt(BufferedReader reader, BlockingQueue<QueueMessage> blockingQueue) {
(new Thread(() -> {
while (true) {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter message: ");
String message = null;
try {
message = inFromUser.readLine();
} catch (IOException e) {
e.printStackTrace();
}
//prompts for dest node to set for later
System.out.print("Enter destination node: ");
int destNode = 0;
try {
destNode = Integer.parseInt(reader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
// TODO this is supposed to be wrapped in headers to avoid what I'm doing in this next line
message = MESSAGETONODE + " " + destNode + " " + sourceNode + " " + message;
blockingQueue.add(new QueueMessage(Client.MESSAGETONODE, message, destNode, sourceNode, getTimeInMS()));
}
})).start();
}
public static void assignFromFile(String itcFile) throws FileNotFoundException {
// reads from the file you initially set in the running prompt
Scanner docScan = new Scanner(new File(itcFile + ".txt"));
String data;
// final Node NODE;
// reads each line of the text files
while (docScan.hasNextLine()) {
data = docScan.nextLine();
// System.out.println(data);
String[] word = data.split(" ");
// sets each variable of the documents to a Node
final Node NODE = new Node(Integer.parseInt(word[0]), word[1], Integer.parseInt(word[2]),
Integer.parseInt(word[3]), Integer.parseInt(word[4]), Integer.parseInt(word[5]));
linkNode.add(NODE);
}
}
public static void startSender() {
(new Thread() {
@Override
public void run() {
try {
// Gets input from user
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
// Sets a socket that connects to the port of the nodeID you set in the beginning prompt
// Socket s = new Socket("localhost", sourcePort);
for (Node n : linkNode) {
if (destNode == n.getNodeID())
destPort = n.getPortNumber();
}
DatagramSocket socket = new DatagramSocket();
DatagramPacket msg = new DatagramPacket(new byte[0], 0, InetAddress.getByName("localhost"), destPort);
while (true) {
/// takes the next available message from blockingQueue
QueueMessage queueMessage = blockingQueue.take();
String type = queueMessage.getMessageType();
// TODO: this is the method that executes the function of transport layer, supposed to
byte[] bbuf;
if (type != null) {
int destNode = queueMessage.getDestinationNID();
int destPort = networkLayer.routeMessage(queueMessage);
if (destPort == NetworkLayer.INF) continue;
if (queueMessage.getMessage() == null) break;
TransportLayer transportLayer = new TransportLayer(queueMessage.getSourceNID(),
networkLayer.getNodePort(queueMessage.getSourceNID()),
queueMessage.getDestinationNID(), destPort, queueMessage.getMessage());
String message = transportLayer.sendData(queueMessage.getDestinationNID(),
queueMessage.getMessage());
transportLayer.setMessage(message);
bbuf = message.getBytes();
msg.setData(bbuf);
msg.setLength(message.length());
msg.setPort(destPort);
try {
LinkLayer.garble(msg.getData());
socket.send(msg);
} catch (IOException ioe) {
System.err.println("send() failed");
return;
}
if (queueMessage.getMessageType()==MESSAGETONODE) {
}
}
}
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public static void startServer(int port) {
new Thread() {
@Override
public void run() {
ServerSocket ss;
ServerSocket destSocket;
DatagramSocket dSocket;
int bufSize = 512;
try {
// creates a server on the port of the nodeID you set in the beginning prompt
dSocket = new DatagramSocket(port);
} catch (SocketException se) {
System.err.println("cannot create socket with port: " + port);
return;
}
try {
dSocket.setSoTimeout(15000);
} catch (SocketException se) {
System.err.println("Socekt exception: timeout not set");
}
DatagramPacket msg = new DatagramPacket(new byte[bufSize], bufSize);
while (true) {
try {
msg.setLength(bufSize);
dSocket.receive(msg);
} catch (SocketTimeoutException ste) {
System.err.println("response timed out");
continue;
} catch (IOException ioe) {
System.err.println("Bad receive");
break;
}
String str = new String(msg.getData(), 0, msg.getLength());
TransportLayer transportLayer = new TransportLayer();
transportLayer.setMessage(str);
int checksum = transportLayer.receiveChecksum();
transportLayer.receiveHeaders();
str = transportLayer.getMessage();
if (str.startsWith(CHECKMESSAGE)) {
// TODO: Implement the function getSenderIDFromMsg that takes the DatagramaPakcet msg as an
// argument and gives back the node ID of the sender
int senderNode = Integer.parseInt(str.substring(CHECKMESSAGE.length() + 1));
blockingQueue.add(new QueueMessage(PING, PINGMESSAGE + " " + sourceNode, senderNode,
sourceNode, getTimeInMS()));
} else if (str.startsWith(PINGMESSAGE)) {
int senderNode = Integer.parseInt(str.substring(PINGMESSAGE.length() + 1));
int neighborIndex = networkLayer.getNeighborIndex(senderNode);
PINGQueue.get(neighborIndex).add(new QueueMessage(PING, PINGMESSAGE, 0, sourceNode,
getTimeInMS()));
} else {
if (str.startsWith(MESSAGETONODE)) {
Scanner stringstream = new Scanner(str);
String type, actualMessage;
int dest, src;
type = stringstream.next();
type = stringstream.next();
type = stringstream.next();
dest = stringstream.nextInt();
src = stringstream.nextInt();
actualMessage = stringstream.next();
if (dest != sourceNode)
blockingQueue.add(new QueueMessage(MESSAGETONODE, str, dest, src, getTimeInMS()));
else {
System.err.println("message from <" + msg.getAddress().getHostAddress() + ","
+ msg.getPort() + ">");
System.out.println(actualMessage);
System.out.println("Checksum received = " + checksum);
}
} else {
Scanner stringstream = new Scanner(str);
String type = stringstream.next();
type = stringstream.next();
int nodeID = stringstream.nextInt();
int src = stringstream.nextInt();
int TTL = stringstream.nextInt();
int neighborIndex = networkLayer.getNeighborIndex(src);
if (str.startsWith(DEATHNOTE)) {
System.out.println("Node " + nodeID + " is dead");
networkLayer.setNodeDead(nodeID);
if (TTL > 1) {
for (int i = 0; i < networkLayer.getNeighborsCount(); ++i)
if (i != neighborIndex)
blockingQueue.add(new QueueMessage(DEATHNOTE, DEATHNOTE + " " +
nodeID + " " + src + " " + Integer.toString(TTL - 1),
networkLayer.getNeighborNID(i), sourceNode, getTimeInMS()));
}
} else {
System.out.println("Node " + nodeID + " is alive");
networkLayer.setNodeAlive(nodeID);
if (TTL > 1) {
for (int i = 0; i < networkLayer.getNeighborsCount(); ++i)
if (i != neighborIndex)
blockingQueue.add(new QueueMessage(BIRTHCERT, BIRTHCERT + " " +
nodeID + " " + src + " " + Integer.toString(TTL - 1),
networkLayer.getNeighborNID(i), sourceNode, getTimeInMS()));
}
}
}
}
}
}
}.start();
}
public static long getTimeInMS() {
return System.currentTimeMillis();
}
}
And here is the garbler class
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Random;
public class LinkLayer {
int destPort, sourcePort, sourceNode, destNode, transmissionBytes;
String message;
public LinkLayer(int sourceNode, int sourcePort, int destNode, int destPort, String message) {
this.sourceNode = sourceNode;
this.sourcePort = sourcePort;
this.destNode = destNode;
this.destPort = destPort;
this.message = message;
}
public boolean sendData(int destinationNID, String message, int tlCheckSum) throws FileNotFoundException, UnsupportedEncodingException {
byte[] nMsg = garble(message.getBytes());
// System.out.println("CHECKSUM = " + tlCheckSum);
String msg = new String(nMsg);
msg = createHeader(msg);
// System.out.println(message + ' ' + msg);
// System.out.println("CHECKSUM = " + createChecksum(msg));
return tlCheckSum == createChecksum(msg);
}
private String createHeader(String message) throws FileNotFoundException {
byte srcPort;
byte dPort;
byte[] ports = new byte[2];
srcPort = (byte) sourcePort;
dPort = (byte) destPort;
ports[0] = srcPort;
ports[1] = dPort;
message = ports[0] + " " + ports[1] + " " + message;
// calls the method to create the checksum
return message;
}
public int[] stringToArray(String message) throws UnsupportedEncodingException {
ByteBuffer bytes = ByteBuffer.wrap(message.getBytes("UTF-8"));
// you must specify a charset
IntBuffer ints = bytes.asIntBuffer();
int numInts = ints.remaining();
int[] result = new int[numInts];
ints.get(result);
return result;
}
public int createChecksum(String message) throws FileNotFoundException, UnsupportedEncodingException {
int maxSize = 0;
int length = message.length();
// set the maximum size of the data with the MTU's from the file
for (Node node : Client.linkNode) {
if (sourceNode == node.getNodeID()) {
maxSize = node.getMtuBytes();
transmissionBytes = maxSize;
}
}
// array to hold the max size for the data being sent
int data[] = stringToArray(message);
// array to hold the max size for the compliment of the data
int complimentData[] = new int[maxSize];
int numBits = 0;
int checkSum = 0, i;
// creating the checksum for the length of data in the message
for (i = 0; i < data.length; i++) {
numBits = (int) (Math.floor(Math.log(data[i]) / Math.log(2))) + 1;
// compliments the checksum
complimentData[i] = ((1 << numBits) - 1) ^ data[i];
// adding the complimented data
checkSum += complimentData[i];
}
// creates the sum of the checksum
// data[i] = checkSum;
length += 1;
return checkSum;
// adds the checksum to the "header"
// NetworkLayer nl = new NetworkLayer(sourceNode, destNode, transmissionBytes, message);
// nl.routingTable();
}
public static byte[] garble(byte[] data) {
// Garble/drop the packet
for (byte b : data) System.out.print(b + " ");
int C = 5; // packet corruption fraction (between 0 and 100)
Random rand = new Random(); // random generator
int randInt = rand.nextInt(101);
if (randInt < C) { // corrupt the packet
int randomLocationToGarble = 0; // holds the byte location of the packet to be garbled
// Corrupt the packet
if (data.length > 0) { // Determine the size of the packet
randomLocationToGarble = rand.nextInt(data.length);
data[randomLocationToGarble] = (byte) (~((int) data[randomLocationToGarble]));
}
}
System.out.println();
for (byte b : data) System.out.print(b + " ");
System.out.println();
return data;
}
}
Comments
Post a Comment