diff --git a/ReliableUDPPacket.java b/ReliableUDPPacket.java new file mode 100644 index 0000000..acf350c --- /dev/null +++ b/ReliableUDPPacket.java @@ -0,0 +1,38 @@ +import java.nio.*; +//import org.jnetpcap.nio.*; +import org.jnetpcap.protocol.tcpip.Udp; + +public class ReliableUDP extends Udp //Seems like an appropriate place to start +{ + private int totalPackets; + private int seqNumber; + + public ReliableUDP(){ + super(); + + ByteBuffer bb = ByteBuffer.allocate(2); + byte[] buf = new byte[2]; + + //This is the best way I could think of to do this - get the relevant bytes, + //move them into an array, and derive the field values from there. + + this.transferTo(bb,8,2); + bb.get(buf); + seqNumber = (buf[1] << 8) + buf[0]; + + this.transferTo(bb,10,2); + bb.get(buf); + totalPackets = (buf[1] << 8) + buf[0]; + + } + + @Field(offset=64,length=16) + public int seqNumber(){ + return seqNumber; + } + + @Field(offset=80,length=16,description="Total number of packets in this transmission") + public int totalPackets(){ + return totalPackets; + } +} diff --git a/udpClient.java b/udpClient.java index dd12ec1..3c37af2 100644 --- a/udpClient.java +++ b/udpClient.java @@ -3,6 +3,9 @@ class udpClient{ + String filename; + ArrayList packetData; + public static void main(String args[]) throws Exception{ int port; DatagramSocket clientSocket = new DatagramSocket(); @@ -15,8 +18,12 @@ public static void main(String args[]) throws Exception{ port = Integer.parseInt(inFromUser.readLine()); System.out.print("Filename: "); - String fileName = inFromUser.readLine(); + fileName = inFromUser.readLine(); byte[] sendData = new byte[1024]; + //what if the filename takes more than 1024 bytes? i highly doubt this but it + ////seems like we should have to make a loop that will just copy the bytes into + ////the array into place. otherwise, the server may be waiting for bytes that it + ////won't receive if the fileName.getBytes is less than 1024 sendData = fileName.getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); @@ -25,9 +32,139 @@ public static void main(String args[]) throws Exception{ byte[] recvData = new byte[1024]; DatagramPacket recvPacket = new DatagramPacket(recvData, recvData.length); clientSocket.receive(recvPacket); + recvData = recvPacket.getData(); + + int packetCount = analyzePacketTotal(recvData); + + //this should keep receiving data, then put it in the arraylist based + //on its sequence number - Brett + DatagramPacket recvPacket = new DatagramPacket(recvData, recvData.length); + for(int i=0; i missingPackets = ArrayList(); + missingPackets = checkData(packetData); + int missingCount = missingPackets.size(); + + do{ + String missingString = ""; + for(int i=0; i0); + + + //I don't know what this is supposed to do. the server isn't really saying anything, + ////it's receiving a file. - Brett String newMessage = new String(recvData); System.out.println("Server says: " + newMessage); + clientSocket.close(); } + + private boolean checkCheckSum(int checkSum, byte[] recvData){ + int recvCheckSum = checkSum; + int ourCheckSum = 0; + for(int i =0; i < recvData.length; i++){ + if(recvData[i]==1) + ourCheckSum += (int)recvData[i]; + } + + if(ourCheckSum == recvCheckSum){ + return true; + }else{ + return false; + } + } + + //Get data from packet + private byte[] analyzeData(byte[] recvData){ + byte[928] data; + for(int i = 32; i < recvData.length; i++){ + data[i] = recvData[i]; + } + return data; + } + + //Get sequence number header from packet + private int analyzeSeqNum(byte[] recvData){ + byte[16] data; + for(int i = 0; i < 16; i++){ + data[i] = recvData[i]; + } + //found this online for convering from byte[] to int + //http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java + // - Brett + int index = 0; + int value = data[index++] << Byte.SIZE * 3; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 2; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 1; + value ^= (data[index++] & 0xFF); + return value; + } + + //Get packet total header from packet + private int analyzePacketTotal(byte[] recvData){ + byte[16] data; + for(int i = 16; i < 32; i++){ + data[i] = recvData[i]; + } + //found this online for convering from byte[] to int + //http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java + // - Brett + int index = 0; + int value = data[index++] << Byte.SIZE * 3; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 2; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 1; + value ^= (data[index++] & 0xFF); + return value; + } + + //Write the values we've received to filename + private void writeToFile(){ //throws IOException? or just try/catch? + try{ + FileOutputStream fos = new FileOutputStream(new File(filename)); + for(ArrayList b : packetData){ + fos.write(b.toArray()); + } + }catch(IOException e){System.out.println("Error writing to file "+filename);} + } + + private ArrayList checkData(ArrayList packetData){ + ArrayList missing = new ArrayList(); + int size = packetData.size(); + for(int i=0; i packetData = new ArrayList(); + for(int m = 0; m < packetCount; m++){ + packetData.add(null); + } + System.out.println("Num packets: " + packetCount + " length: " + packetData.size()); + + //this should keep receiving data, then put it in the arraylist based + //on its sequence number - Brett + //DatagramPacket + recvPacket = new DatagramPacket(recvData, recvData.length); + try{ + for(int i=0; i missingPackets = new ArrayList(); + missingPackets = checkData(packetData); + int missingCount = missingPackets.size(); + String missingString; + System.out.println("Missing count: " + missingCount); + do{ + missingString = ""; + for(int i=0; i0); + + + //I don't know what this is supposed to do. the server isn't really saying anything, + ////it's receiving a file. - Brett + //String newMessage = new String(recvData); + //System.out.println("Server says: " + newMessage); + + writeToFile(packetData); + clientSocket.close(); + + + } + + private static boolean checkCheckSum(int checkSum, byte[] recvData){ + int recvCheckSum = checkSum; + int ourCheckSum = 0; + for(int i =0; i < recvData.length; i++){ + if(recvData[i]==1) + ourCheckSum += (int)recvData[i]; + } + + if(ourCheckSum == recvCheckSum){ + return true; + }else{ + return false; + } + } + + //Get data from packet + private static byte[] analyzeData(byte[] recvData){ + byte[] data = new byte[1016]; + for(int i = 4; i < recvData.length; i++){ + data[i-4] = recvData[i]; + } + return data; + } + + //Get sequence number header from packet + private static short analyzeSeqNum(byte[] recvData){ + byte[] data = new byte[2]; + for(int i = 0; i < 2; i++){ + data[i] = recvData[i]; + } + //found this online for convering from byte[] to int + //http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java + // - Brett + //int index = 0; + short value = (short) ((data[0] << 8) | (data[1]& 0xFF)); + /*int value = data[index++] << Byte.SIZE * 3; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 2; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 1; + value ^= (data[index++] & 0xFF);*/ + System.out.println("Seq num: " + value); + return value; + } + + //Get packet total header from packet + private static short analyzePacketTotal(byte[] recvData){ + byte[] data = new byte[2]; + System.out.println(recvData.length); + for(int i = 2; i < 4; i++){ + data[i-2] = recvData[i]; + } + //found this online for convering from byte[] to int + //http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java + // - Brett + //int index = 0; + short value = (short) (((data[0]) << 8) | (data[1]& 0xFF)); + /*int value = data[index++] << Byte.SIZE * 3; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 2; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 1; + value ^= (data[index++] & 0xFF);*/ + System.out.println("Total packets: " + value); + return value; + } + + //Write the values we've received to filename + private static void writeToFile(ArrayList packetData){ //throws IOException? or just try/catch? + try{ + FileOutputStream fos = new FileOutputStream(new File("temp" + fileName)); + for(byte[] b : packetData){ + fos.write(b); + } + fos.close(); + }catch(IOException e){System.out.println("Error writing to file " + fileName);} + } + + private static ArrayList checkData(ArrayList packetData){ + ArrayList missing = new ArrayList(); + int size = packetData.size(); + System.out.println(packetData.size()); + for(int i=0; i packetData; + + public static void main(String args[]) throws Exception{ + int port; + DatagramSocket clientSocket = new DatagramSocket(); + BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); + System.out.print("IP Address: "); + //String address = new String(inFromUser.readLine()); + String address = new String("148.61.112.70"); + InetAddress IPAddress = InetAddress.getByName(address); + + System.out.print("Port #: "); + //port = Integer.parseInt(inFromUser.readLine()); + port = 9876; + + System.out.print("Filename: "); + fileName = inFromUser.readLine(); + byte[] sendData = new byte[1024]; + //what if the filename takes more than 1024 bytes? i highly doubt this but it + ////seems like we should have to make a loop that will just copy the bytes into + ////the array into place. otherwise, the server may be waiting for bytes that it + ////won't receive if the fileName.getBytes is less than 1024 + sendData = fileName.getBytes(); + + DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); + clientSocket.send(sendPacket); + + byte[] recvData = new byte[1024]; + DatagramPacket recvPacket = new DatagramPacket(recvData, recvData.length); + clientSocket.receive(recvPacket); + recvData = recvPacket.getData(); + + int packetCount = analyzePacketTotal(recvData); + + //this should keep receiving data, then put it in the arraylist based + //on its sequence number - Brett + //DatagramPacket + recvPacket = new DatagramPacket(recvData, recvData.length); + for(int i=0; i missingPackets = new ArrayList(); + missingPackets = checkData(packetData); + int missingCount = missingPackets.size(); + + do{ + String missingString = ""; + for(int i=0; i0); + + + //I don't know what this is supposed to do. the server isn't really saying anything, + ////it's receiving a file. - Brett + String newMessage = new String(recvData); + System.out.println("Server says: " + newMessage); + + clientSocket.close(); + } + + private static boolean checkCheckSum(int checkSum, byte[] recvData){ + int recvCheckSum = checkSum; + int ourCheckSum = 0; + for(int i =0; i < recvData.length; i++){ + if(recvData[i]==1) + ourCheckSum += (int)recvData[i]; + } + + if(ourCheckSum == recvCheckSum){ + return true; + }else{ + return false; + } + } + + //Get data from packet + private static byte[] analyzeData(byte[] recvData){ + byte[] data = new byte[1012]; + for(int i = 12; i < recvData.length; i++){ + data[i] = recvData[i]; + } + return data; + } + + //Get sequence number header from packet + private static int analyzeSeqNum(byte[] recvData){ + byte[] data = new byte[2]; + for(int i = 8; i < 10; i++){ + data[i-8] = recvData[i]; + } + //found this online for convering from byte[] to int + //http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java + // - Brett + //int index = 0; + short value = (short) ((data[1] << 8) + (data[0]&0xFF)); + /*int value = data[index++] << Byte.SIZE * 3; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 2; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 1; + value ^= (data[index++] & 0xFF);*/ + return value; + } + + //Get packet total header from packet + private static int analyzePacketTotal(byte[] recvData){ + byte[] data = new byte[2]; + System.out.println(recvData.length); + for(int i = 10; i < 12; i++){ + data[i-10] = recvData[i]; + } + //found this online for convering from byte[] to int + //http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java + // - Brett + //int index = 0; + short value = (short) ((data[1] << 8) + (data[0]&0xFF)); + /*int value = data[index++] << Byte.SIZE * 3; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 2; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 1; + value ^= (data[index++] & 0xFF);*/ + return value; + } + + //Write the values we've received to filename + private void writeToFile(){ //throws IOException? or just try/catch? + try{ + FileOutputStream fos = new FileOutputStream(new File(fileName)); + for(byte[] b : packetData){ + fos.write(b); + } + }catch(IOException e){System.out.println("Error writing to file " + fileName);} + } + + private static ArrayList checkData(ArrayList packetData){ + ArrayList missing = new ArrayList(); + int size = packetData.size(); + for(int i=0; i packetData = new ArrayList(); + for(int m = 0; m < packetCount; m++){ + packetData.add(null); + } + System.out.println("Num packets: " + packetCount + " length: " + packetData.size()); + + //this should keep receiving data, then put it in the arraylist based + //on its sequence number - Brett + //DatagramPacket + recvPacket = new DatagramPacket(recvData, recvData.length); + try{ + for(int i=0; i missingPackets = new ArrayList(); + missingPackets = checkData(packetData); + int missingCount = missingPackets.size(); + String missingString; + System.out.println("Missing count: " + missingCount); + + try{ + do{ + missingString = ""; + for(int i=0; i0); + }catch(SocketTimeoutException e){ + System.out.println("Timeout."); + } + + writeToFile(packetData); + clientSocket.close(); + } + + private static boolean checkCheckSum(int recvCheckSum, byte[] recvData){ + long ourCheckSum = 0; + for (int i = 0; i < recvData.length; i++) { + if(i < 4 || i > 7) + ourCheckSum += (recvData[i] & 0xFF); + } + ourCheckSum = ourCheckSum & 0xFFFFFFFFL; + + System.out.println(ourCheckSum); + if((int)ourCheckSum == recvCheckSum){ + return true; + }else{ + return false; + } + } + + //Get data from packet + private static byte[] analyzeData(byte[] recvData){ + int count = 0; + + for(int j = 0; j < recvData.length; j++){ + if(!(recvData[j] == 0)) + count++; + } + byte[] data = new byte[count-4]; + for(int i = 4; i < data.length; i++){ + data[i-4] = recvData[i]; + } + return data; + } + + //Get sequence number header from packet + private static short analyzeSeqNum(byte[] recvData){ + byte[] data = new byte[2]; + for(int i = 0; i < 2; i++){ + data[i] = recvData[i]; + } + short value = (short) ((data[0] << 8) | (data[1]& 0xFF)); + System.out.println("Seq num: " + value); + return value; + } + + /*private static int getCheckSum(byte[] recvData){ + //int index = 4; + //int value = recvData[index++] << Byte.SIZE * 3; + //value ^= (recvData[index++] & 0xFF) << Byte.SIZE * 2; + //value ^= (recvData[index++] & 0xFF) << Byte.SIZE * 1; + //value ^= (recvData[index++] & 0xFF); + + int i = ((0xFF & recvData[4]) << 24) | ((0xFF & recvData[5]) << 16) | + ((0xFF & recvData[6]) << 8) | (0xFF & recvData[7]); + System.out.println("Checksum: " + i); + return i; + }*/ + + //Get packet total header from packet + private static short analyzePacketTotal(byte[] recvData){ + byte[] data = new byte[2]; + System.out.println(recvData.length); + for(int i = 2; i < 4; i++){ + data[i-2] = recvData[i]; + } + short value = (short) (((data[0]) << 8) | (data[1]& 0xFF)); + System.out.println("Total packets: " + value); + return value; + } + + //Write the values we've received to filename + private static void writeToFile(ArrayList packetData){ //throws IOException? or just try/catch? + try{ + FileOutputStream fos = new FileOutputStream(new File("temp" + fileName)); + for(byte[] b : packetData){ + fos.write(b); + } + fos.close(); + }catch(IOException e){System.out.println("Error writing to file " + fileName);} + } + + private static ArrayList checkData(ArrayList packetData){ + ArrayList missing = new ArrayList(); + int size = packetData.size(); + System.out.println(packetData.size()); + for(int i=0; i missing = new ArrayList(Arrays.asList(missing.split(","))); + int numLeft = missing.size(); + + if(numLeft>0){ + for(int i = 0; i < numLeft; i++){ + int packetNum = missing.get(i); + DatagramPacket sendPacket = new DatagramPacket(fragSendData[packetNum], fragSendData[packetNum].length, IPAddress, port); + serverSocket.send(sendPacket); + } + } else { + incomplete = false; + } + } } } + + //changed the copy of the array to make sure there was no pointer issue. - brett + //changed the checksum value. even if the client received incorrect data, it would've all + ////been counted and would've appeared to be correct. + private int makeCheckSum(byte[] sendData){ + byte[] data = (byte[])sendData.clone(); + + int checkSum = 0; + + for(int i = 0; i < data.length(); i++){ + if(data[i]==1) + checkSum += (int)data[i]; + } + + return checkSum; + } + + //Method that fragments data into appropriate sizes in an array + //928 bits of data = 116 bytes + // Also adds in the extra data for the extended header + private static byte[][] fragmentData(byte[] sendData){ + int length = sendData.length; + int numOfFrags = (length / 116) + 1; + byte[][] fragData = new byte[numOfFrags][120]; + for(int counter = 0; counter < length; counter++){ + byte[] seqNum = ByteBuffer.allocate(2).putInt(counter).array(); + byte[] totalNum = ByteBuffer.allocate(2).putInt(numOfFrags).array(); + fragData[counter][0] = seqNum[0]; + fragData[counter][1] = seqNum[1]; + fragData[counter][2] = totalNum[0]; + fragData[counter][3] = totalNum[1]; + for(int counter2 = 4; counter2 < 120; counter2++){ + fragData[counter][counter2] = sendData[counter]; + } + } + return fragData; + } } diff --git a/udpServerCloser.java b/udpServerCloser.java new file mode 100644 index 0000000..920312b --- /dev/null +++ b/udpServerCloser.java @@ -0,0 +1,200 @@ +import java.io.*; +import java.net.*; +import java.util.*; + +class udpClient{ + + static String fileName; + + public static void main(String args[]) throws Exception{ + int port; + DatagramSocket clientSocket = new DatagramSocket(); + clientSocket.setSoTimeout(2000); + BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); + System.out.print("IP Address: "); + //String address = new String(inFromUser.readLine()); + String address = new String("148.61.112.70"); + InetAddress IPAddress = InetAddress.getByName(address); + + System.out.print("Port #: "); + //port = Integer.parseInt(inFromUser.readLine()); + port = 9876; + + System.out.print("Filename: "); + fileName = inFromUser.readLine(); + byte[] sendData = new byte[1016]; + //what if the filename takes more than 1024 bytes? i highly doubt this but it + ////seems like we should have to make a loop that will just copy the bytes into + ////the array into place. otherwise, the server may be waiting for bytes that it + ////won't receive if the fileName.getBytes is less than 1024 + sendData = fileName.getBytes(); + + DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); + clientSocket.send(sendPacket); + + byte[] recvData = new byte[1016]; + DatagramPacket recvPacket = new DatagramPacket(recvData, recvData.length); + clientSocket.receive(recvPacket); + recvData = recvPacket.getData(); + + int packetCount = (int)(analyzePacketTotal(recvData)); + ArrayList packetData = new ArrayList(); + for(int m = 0; m < packetCount; m++){ + packetData.add(null); + } + System.out.println("Num packets: " + packetCount + " length: " + packetData.size()); + + //this should keep receiving data, then put it in the arraylist based + //on its sequence number - Brett + //DatagramPacket + recvPacket = new DatagramPacket(recvData, recvData.length); + try{ + for(int i=0; i missingPackets = new ArrayList(); + missingPackets = checkData(packetData); + int missingCount = missingPackets.size(); + String missingString; + System.out.println("Missing count: " + missingCount); + do{ + missingString = ""; + for(int i=0; i0); + + + //I don't know what this is supposed to do. the server isn't really saying anything, + ////it's receiving a file. - Brett + //String newMessage = new String(recvData); + //System.out.println("Server says: " + newMessage); + + writeToFile(packetData); + clientSocket.close(); + + + } + + private static boolean checkCheckSum(int checkSum, byte[] recvData){ + int recvCheckSum = checkSum; + int ourCheckSum = 0; + for(int i =0; i < recvData.length; i++){ + if(recvData[i]==1) + ourCheckSum += (int)recvData[i]; + } + + if(ourCheckSum == recvCheckSum){ + return true; + }else{ + return false; + } + } + + //Get data from packet + private static byte[] analyzeData(byte[] recvData){ + byte[] data = new byte[1016]; + for(int i = 4; i < recvData.length; i++){ + data[i-4] = recvData[i]; + } + return data; + } + + //Get sequence number header from packet + private static short analyzeSeqNum(byte[] recvData){ + byte[] data = new byte[2]; + for(int i = 0; i < 2; i++){ + data[i] = recvData[i]; + } + //found this online for convering from byte[] to int + //http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java + // - Brett + //int index = 0; + short value = (short) ((data[0] << 8) | (data[1]& 0xFF)); + /*int value = data[index++] << Byte.SIZE * 3; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 2; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 1; + value ^= (data[index++] & 0xFF);*/ + System.out.println("Seq num: " + value); + return value; + } + + //Get packet total header from packet + private static short analyzePacketTotal(byte[] recvData){ + byte[] data = new byte[2]; + System.out.println(recvData.length); + for(int i = 2; i < 4; i++){ + data[i-2] = recvData[i]; + } + //found this online for convering from byte[] to int + //http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java + // - Brett + //int index = 0; + short value = (short) (((data[0]) << 8) | (data[1]& 0xFF)); + /*int value = data[index++] << Byte.SIZE * 3; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 2; + value ^= (data[index++] & 0xFF) << Byte.SIZE * 1; + value ^= (data[index++] & 0xFF);*/ + System.out.println("Total packets: " + value); + return value; + } + + //Write the values we've received to filename + private static void writeToFile(ArrayList packetData){ //throws IOException? or just try/catch? + try{ + FileOutputStream fos = new FileOutputStream(new File("temp" + fileName)); + for(byte[] b : packetData){ + fos.write(b); + } + fos.close(); + }catch(IOException e){System.out.println("Error writing to file " + fileName);} + } + + private static ArrayList checkData(ArrayList packetData){ + ArrayList missing = new ArrayList(); + int size = packetData.size(); + System.out.println(packetData.size()); + for(int i=0; i missingList = new ArrayList(Arrays.asList(missing.split(","))); + int numLeft = missingList.size(); + + if(numLeft>0){ + for(int i = 0; i < numLeft; i++){ + int packetNum = Integer.parseInt(missingList.get(i)); + DatagramPacket sendPacket = new DatagramPacket(fragSendData[packetNum], fragSendData[packetNum].length, IPAddress, port); + serverSocket.send(sendPacket); + } + } else { + incomplete = false; + } + } + } + } + + //changed the copy of the array to make sure there was no pointer issue. - brett + //changed the checksum value. even if the client received incorrect data, it would've all + ////been counted and would've appeared to be correct. + private static int makeCheckSum(byte[] sendData){ + byte[] data = (byte[])sendData.clone(); + + int checkSum = 0; + + for(int i = 0; i < data.length; i++){ + if(data[i]==1) + checkSum += (int)data[i]; + } + + return checkSum; + } + + //Method that fragments data into appropriate sizes in an array + //928 bits of data = 116 bytes + // Also adds in the extra data for the extended header + private static byte[][] fragmentData(byte[] sendData){ + int pos = 0; + int length = sendData.length; + System.out.println(length); + short numOfFrags = (short)((length / 928) + 1); + byte[][] fragData = new byte[numOfFrags][1016]; + for(short counter = 0; counter < numOfFrags; counter++){ + byte[] seqNum = ByteBuffer.allocate(2).putShort(counter).array(); + byte[] totalNum = ByteBuffer.allocate(2).putShort(numOfFrags).array(); + fragData[counter][0] = seqNum[0]; + fragData[counter][1] = seqNum[1]; + fragData[counter][2] = totalNum[0]; + fragData[counter][3] = totalNum[1]; + int counter2 = 4; + while(pos < length && counter2 < 1016){ + //for(int counter2 = 4; counter2 < 1016; counter2++){ + fragData[counter][counter2] = sendData[pos]; + counter2++; + pos++; + } + } + return fragData; + } +} diff --git a/udpServerFinal.java b/udpServerFinal.java new file mode 100644 index 0000000..626254f --- /dev/null +++ b/udpServerFinal.java @@ -0,0 +1,122 @@ +import java.io.*; +import java.net.*; +import java.nio.*; +import java.nio.file.*; +import java.util.*; + +class udpServer{ + public static void main(String args[]) throws Exception{ + DatagramSocket serverSocket = new DatagramSocket(9876); + while(true){ + byte[] recvData = new byte[1016]; + byte[] sendData;// = new byte[1024]; + + DatagramPacket recvPacket = new DatagramPacket(recvData, recvData.length); + serverSocket.receive(recvPacket); + + String fileName = new String(recvPacket.getData()).trim(); + System.out.println(fileName); + + try{ + File file = new File(fileName); + sendData = Files.readAllBytes(file.toPath()); + + InetAddress IPAddress = recvPacket.getAddress(); + + int port = recvPacket.getPort(); + + + //int checkSum = makeCheckSum(sendData); + + byte[][] fragSendData = fragmentData(sendData); + int totalNumberOfPackets = fragSendData.length; + System.out.println("Num packets: " + totalNumberOfPackets); + for(int i = 0; i < totalNumberOfPackets; i++){ + DatagramPacket sendPacket = new DatagramPacket(fragSendData[i], fragSendData[i].length, IPAddress, port); + serverSocket.send(sendPacket); + } + + //receive more data to check for missing or incorrect packet transmission + int numLeft = 1; + while(numLeft > 0){ + System.out.println("Entered resend cycle..."); + serverSocket.receive(recvPacket); + String missing = new String(recvPacket.getData()).trim(); + + System.out.println(missing); + + List missingList = new ArrayList(Arrays.asList(missing.split(","))); + numLeft = missingList.size(); + + if(numLeft>0){ + for(int i = 0; i < numLeft; i++){ + try{ + int packetNum = Integer.parseInt(missingList.get(i)); + DatagramPacket sendPacket = new DatagramPacket(fragSendData[packetNum], fragSendData[packetNum].length, IPAddress, port); + serverSocket.send(sendPacket); + }catch(NumberFormatException b){ + missingList.remove(i); + numLeft--; + } + } + } + } + System.out.println("Left resend cycle..."); + }catch(FileNotFoundException e){ + System.out.println("Invalid file."); + }catch(SocketTimeoutException v){ + System.out.println("Timeout."); + } + } + } + + //changed the copy of the array to make sure there was no pointer issue. - brett + //changed the checksum value. even if the client received incorrect data, it would've all + ////been counted and would've appeared to be correct. + private static int makeCheckSum(byte[] sendData){ + long checksum = 0; + for (int i = 0; i < sendData.length; i++) { + checksum += (sendData[i] & 0xFF); + } + checksum = checksum & 0xFFFFFFFFL; + return (int)checksum; + } + + //Method that fragments data into appropriate sizes in an array + //928 bits of data = 116 bytes + // Also adds in the extra data for the extended header + private static byte[][] fragmentData(byte[] sendData){ + int pos = 0; + int length = sendData.length; + System.out.println(length); + short numOfFrags = (short)((length / 1012) + 1); + byte[][] fragData = new byte[numOfFrags][1016]; + for(short counter = 0; counter < numOfFrags; counter++){ + int counter2 = 4; + while(pos < length && counter2 < 1016){ + //for(int counter2 = 4; counter2 < 1016; counter2++){ + fragData[counter][counter2] = sendData[pos]; + counter2++; + pos++; + } + byte[] seqNum = ByteBuffer.allocate(2).putShort(counter).array(); + byte[] totalNum = ByteBuffer.allocate(2).putShort(numOfFrags).array(); + fragData[counter][0] = seqNum[0]; + fragData[counter][1] = seqNum[1]; + fragData[counter][2] = totalNum[0]; + fragData[counter][3] = totalNum[1]; + + /*int check = makeCheckSum(fragData[counter]); + byte[] checkSum = ByteBuffer.allocate(4).putInt(check).array(); + + System.out.println("Checksum: " + check); + + fragData[counter][4] = checkSum[0]; + fragData[counter][5] = checkSum[1]; + fragData[counter][4] = checkSum[2]; + fragData[counter][5] = checkSum[3];*/ + System.out.println("Num frags: " + numOfFrags); + } + return fragData; + } +}