diff --git a/sequence.jpg b/internetworking_ws23.zip similarity index 52% rename from sequence.jpg rename to internetworking_ws23.zip index f8af87353d2ac0fbb00998f45d8b6e89382cfcd4..01f158f5eb24e0e81a0330b0d7cd80a898c76c65 100644 Binary files a/sequence.jpg and b/internetworking_ws23.zip differ diff --git a/src/main/java/cp/StatusCommandMessage.java b/src/main/java/cp/CPCommandMessage.java similarity index 58% rename from src/main/java/cp/StatusCommandMessage.java rename to src/main/java/cp/CPCommandMessage.java index f5bf87ff14681cfcb94d3a5880142e5a32470124..df0b58935ffe05788769cfab77e2a463166a2e23 100644 --- a/src/main/java/cp/StatusCommandMessage.java +++ b/src/main/java/cp/CPCommandMessage.java @@ -1,64 +1,56 @@ package cp; -import core.Msg; +import exceptions.IllegalCommandException; import java.util.zip.CRC32; import java.util.zip.Checksum; -public class StatusCommandMessage extends CPMsg{ - - private String cookie; - private String command; - private String message; - private String data; +public class CPCommandMessage extends CPMsg{ private static int messageIdCount = 0; //tracks the IDS private int currentMessageId; private static final int MAX_ID = 65535; //maximum message id according to the protocol specification. protected static final String HEADER = "command"; - public StatusCommandMessage() {} + public CPCommandMessage() {} - public StatusCommandMessage create(String cookie, String command, String message){ + public CPCommandMessage create(String cookie, String command, String message){ + //maybe throw an exception if the ID's run out? if(messageIdCount < MAX_ID){ currentMessageId = messageIdCount; messageIdCount++; } - this.cookie = cookie; - this.command = command; - this.message = message; - StringBuilder str = new StringBuilder(); - str.append("cp").append(' '); str.append(HEADER).append(' '); str.append(currentMessageId).append(' '); str.append(cookie).append(' '); str.append(command).append(' '); - if(message != null && !message.isEmpty())str.append(message).append(' '); //message is optional by protocol specification + if(message != null && !message.isEmpty())str.append(message).append(' '); //message is optional according to protocol specification + + //calls the create method of CPMsg so the header gets added + super.create(str.toString()); this.data = str.toString(); //builds the Frame str.append(calcCRC(this.data)); //calculates the crc and adds it to the Frame - this.data = str.toString(); + this.data = str.toString(); //builds the Frame again, but with the attached checksum + return this; } - public String getData(){ - return this.data; + //returns the unique id of the message + public int getMessageId(){ + return currentMessageId; } - @Override - protected Msg parse(String sentence){ - - String[] split = sentence.split(" "); - - return null; + public static int getMaxMessageId() { + return MAX_ID; } - private long calcCRC(String data) { + public static long calcCRC(String data) { Checksum tmp = new CRC32(); tmp.update(data.getBytes()); return tmp.getValue(); diff --git a/src/main/java/cp/CPCommandResponseMessage.java b/src/main/java/cp/CPCommandResponseMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..036db6c60e4dc17f15b1efbfada848b0d98bcee6 --- /dev/null +++ b/src/main/java/cp/CPCommandResponseMessage.java @@ -0,0 +1,109 @@ +package cp; + +import core.Msg; +import exceptions.IWProtocolException; +import exceptions.IllegalMsgException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CPCommandResponseMessage extends CPMsg{ + + private int currentMessageId; + protected static final String COMRES_HEADER = "comres"; + + CPCommandResponseMessage(){} + + public int getMessageId(){ + return currentMessageId; + } + + @Override + protected Msg parse(String sentence) throws IWProtocolException { + + //dismantelts the received frame into its components + String[] fields = sentence.split(" "); + //the "actual" Message might have whitespaces in it self. so we need to put it back together later with the help of the messageLength field + StringBuilder reconstructedMessage = new StringBuilder(); + int messageLength; + + //first check, to see if the received frame is valid. + if(!fields[0].equals("cp") || !fields[1].equals(COMRES_HEADER)){ + throw new IllegalMsgException(); + } + + try { + this.currentMessageId = Integer.parseInt(fields[2]); + //throws NumberFormatException, if the id couldnt get parsed for whatever reason + + //throws exception if the id from the received message is too large or negative, wich it cant be according to protocol specification + if(currentMessageId > CPCommandMessage.getMaxMessageId() || currentMessageId < 0){ + throw new IllegalMsgException(); + } + }catch (NumberFormatException e){ + throw new IllegalMsgException(); + } + + //sucess ok or error + if(!fields[3].equals("ok") && !fields[3].equals("error")){ + throw new IllegalMsgException(); + } + + //get the length of the actual message. Again, might throw an exception if the length value is not a number for example + try { + messageLength = Integer.parseInt(fields[4]); + }catch (NumberFormatException e){ + throw new IllegalMsgException(); + } + + + /* im not proud of the following code, but it sure works :) */ + + //reconstructes message + int fieldIndex = 5; + int sumLen = 0; + + //calculating the actual length of the message + for (int i = 5; i < fields.length - 1; i++) { + + sumLen += fields[i].length(); //count sum of each real message field + sumLen++; //count whitespace between + } + sumLen--; //dont count the whitespace from the last loop iteration + + //if the legth field is different from the actual message length + if (sumLen > 0) { + if(sumLen != messageLength){ + throw new IllegalMsgException(); + } + } + + /* Doesnt work yet :) + + //calculating and comparing crc + int tmpCRC; + int CRCLen = fields[fields.length - 1].length(); + + + //get the crc + try { + tmpCRC = Integer.parseInt(fields[fields.length-1]); + }catch (NumberFormatException e){ + throw new IllegalMsgException(); + } + + String calcCRC = sentence.substring(0,CRCLen); + + if(tmpCRC != CPCommandMessage.calcCRC(calcCRC)){ + throw new IllegalMsgException(); + }*/ + + //sets the received message as the data, so the client can print it on the console + this.data = reconstructedMessage.toString(); + + + + return this; + } +} diff --git a/src/main/java/cp/CPProtocol.java b/src/main/java/cp/CPProtocol.java index efa18e97adf33a569d72d62bde9c5d3c0f021c60..4a1c619abc0ded5cfef562b060503382603738e2 100644 --- a/src/main/java/cp/CPProtocol.java +++ b/src/main/java/cp/CPProtocol.java @@ -48,8 +48,11 @@ public class CPProtocol extends Protocol { if(cookie != null) { //1.2: 1 b - StatusCommandMessage cmdMsg = new StatusCommandMessage(); - cmdMsg.create(cookie, s, ""); + CPCommandMessage cmdMsg = new CPCommandMessage(); + cmdMsg.create(cookie, s, "status"); + + //remembers the id of the current message, so when it's time to receive wel can check if the id's are the same + this.id = cmdMsg.getMessageId(); //1.2: 1 c PhyProto.send(cmdMsg.getData(), this.PhyConfig); @@ -64,26 +67,30 @@ public class CPProtocol extends Protocol { boolean receving = true; while(receving){ - in = this.PhyProto.receive(CP_TIMEOUT); //1.2: 2 b - CPMsg cpmsg = new StatusCommandMessage(); - cpmsg.create(in.getData()); - - //todo: comparing ids (2. c) + CPMsg cpmsg = new CPCommandResponseMessage(); try { + in = this.PhyProto.receive(CP_TIMEOUT); + //1.2: 2 b in = cpmsg.parse(in.getData()); + } catch (Exception e) { + System.out.println(e.getMessage()); continue; //Discard Message } - receving = false; } + //compare the id from the received message and the earlier sent message + if(((CPCommandResponseMessage) in).getMessageId() != this.id){ + return null; + } + return in; } diff --git a/src/main/java/cp/StatusCommandResponseMessage.java b/src/main/java/cp/StatusCommandResponseMessage.java deleted file mode 100644 index f70dfdf238b6e74f24decab2e1bf272a6dc7438d..0000000000000000000000000000000000000000 --- a/src/main/java/cp/StatusCommandResponseMessage.java +++ /dev/null @@ -1,4 +0,0 @@ -package cp; - -public class StatusCommandResponseMessage extends CPMsg{ -}