Mahlzeit.
Ich habe ein kleines Programm geschrieben zur Datenübertragung via UDP.
Genauer gesagt war das eine Aufgabe innerhalb meines Studiums, daher DatagramSocket bzw. DatagramPacket, später also nicht wundern
(Die lib sorgt für Fehler bei der Übertragung (PacketLoss, Bitfehler, Verzögerung...))
Die Aufgab lautet genauer, eben jene Fehler zu behandeln und trotzdem eine zuverlässige Übertragung umzusetzen.
Rahmenverluste und Verzögerung wurden bereits behandelt, Bei der Prüfsumme zur Bitfehlerbehandlung tritt ein Problem auf:
Das letzte Packet will einfach nicht rüber
Spekulationen:
Das letzte Packet hat zumeist eine andere Länge als die übrigen.
- Die länge übergebe ich jedoch mit und sollte daher kein Problem sein.
Ablauf:
Das Packet besteht aus 3 Teilen:
Sequenznummer[1] + Daten[momentan[59] + CRC32[4] = 64byte
Client sendet Packet,
Server empfängt Packet,
Server erstellt eigene CRC32,
Server vergleicht eigene CRC32 mit mitgesendeter CRC32
True: Ack zurücksenden, False: kein Ack zurücksenden und TimeOut löst Neuversand aus.
Code:
Client (Sender):
Server (Empfänger):
Zur Info: Ich möchte hier nicht die Lösung für mein Studium erschnorren, Das Programm wurde bereits abgenommen und ich konnte meinen Fehler tarnen.
Ich wüsste halt nur verdammt gern warum warum warum
LG und vielen Dank schon jetzt.
Ich habe ein kleines Programm geschrieben zur Datenübertragung via UDP.
Genauer gesagt war das eine Aufgabe innerhalb meines Studiums, daher DatagramSocket bzw. DatagramPacket, später also nicht wundern
(Die lib sorgt für Fehler bei der Übertragung (PacketLoss, Bitfehler, Verzögerung...))
Die Aufgab lautet genauer, eben jene Fehler zu behandeln und trotzdem eine zuverlässige Übertragung umzusetzen.
Rahmenverluste und Verzögerung wurden bereits behandelt, Bei der Prüfsumme zur Bitfehlerbehandlung tritt ein Problem auf:
Das letzte Packet will einfach nicht rüber
Spekulationen:
Das letzte Packet hat zumeist eine andere Länge als die übrigen.
- Die länge übergebe ich jedoch mit und sollte daher kein Problem sein.
Ablauf:
Das Packet besteht aus 3 Teilen:
Sequenznummer[1] + Daten[momentan[59] + CRC32[4] = 64byte
Client sendet Packet,
Server empfängt Packet,
Server erstellt eigene CRC32,
Server vergleicht eigene CRC32 mit mitgesendeter CRC32
True: Ack zurücksenden, False: kein Ack zurücksenden und TimeOut löst Neuversand aus.
Code:
Client (Sender):
Java:
package prak2;
import java.net.*; // we use Sockets
import java.util.zip.*;
public class FileTransferClientUDPjlibcnds {
static int timeDelay = 1000;
static long sendStamp = 0;
static long receiveStamp = 0;
static int highestDelay = 0;
static int fails = 0;
static int packetLossWindow = 20;
public static void main(String args[]) throws Exception{
System.out.println("Client:");
// Arguments: Server name & port & filename to transfer
String srvName = "localhost"; // server Name
int srvPort = Integer.parseInt("23556"); // server UDP port
String filename = "source.txt"; // file Name
// Open datagramm socket
javax.net.DatagramSocket dtgSock;
dtgSock = new javax.net.DatagramSocket();
InetSocketAddress srvSockAddr = new InetSocketAddress(srvName, srvPort);
dtgSock.connect(srvSockAddr);
dtgSock.setSoTimeout(timeDelay);
byte[] puff = new byte[15];
byte[] buf = new byte[45];
byte sn = 0;
byte[] checkSum = new byte[4];
CRC32 cs = new CRC32();
java.io.FileInputStream fr = new java.io.FileInputStream(filename);
int len; // number of bytes written from the file
int seq = 1;
long startTime = System.currentTimeMillis();
while ((len=fr.read(buf,1,buf.length-5))!= -1 && packetLossWindow != 0){
//Sequenznummer einbinden
sn = converter.IntegerToByte(seq);
buf[0] = sn;
//CheckSum einbinden
cs.reset();
cs.update(buf, 0, buf.length-4);
checkSum = converter.convertIntToByteArray((int)cs.getValue());
buf[buf.length-4] = checkSum[0];
buf[buf.length-3] = checkSum[1];
buf[buf.length-2] = checkSum[2];
buf[buf.length-1] = checkSum[3];
DatagramPacket packet = new DatagramPacket(buf, len+5);
send(packet,puff,dtgSock);
seq++;
if(seq==100) seq = 1;
}
// Send an empty packet to the server to indicate end of file
DatagramPacket packet = new DatagramPacket(buf, 0);
dtgSock.send(packet);
dtgSock.close(); // Close the Socket
System.out.println("Elapsed Time: "+(double)((System.currentTimeMillis()-startTime)/1000)+" Sekunden");
System.out.println("Lost Packets: "+fails);
}
public static void send(DatagramPacket p, byte[] puff, DatagramSocket dtgSock){
try{
sendStamp = System.currentTimeMillis();
dtgSock.send(p);
//System.out.print("*");
DatagramPacket ackpacket = new DatagramPacket(puff, puff.length);
dtgSock.receive(ackpacket);
receiveStamp = System.currentTimeMillis();
if((receiveStamp-sendStamp)>highestDelay){
highestDelay = (int)(receiveStamp-sendStamp);
dtgSock.setSoTimeout(highestDelay*2);
}
//System.out.println("SN: " + converter.FetchSn(ackpacket.getData()));
//System.out.println("Timer: " + dtgSock.getSoTimeout() + " ms");
packetLossWindow = 20;
} catch(Exception e){
//System.out.println("packetloss...");
fails++;
packetLossWindow--;
if(packetLossWindow==0) System.out.println("disconnect...");
else send(p, puff, dtgSock);
}
}
}
Server (Empfänger):
Java:
package prak2;
import java.net.*; // we use Sockets
import java.util.zip.*;
public class FileTransferServerUDPjlibcnds {
public static void main(String args[]) throws Exception{
System.out.println("Server:");
// Arguments: port & filename
int srvPort = Integer.parseInt("23556"); // server UDP port
String filename = "dest/sink.txt"; // file Name
// Open datagramm socket
javax.net.DatagramSocket dtgSock;
dtgSock = new javax.net.DatagramSocket(srvPort);
byte[] buf = new byte[4000];
int seq = 0;
byte[] seqArr = new byte[1];
byte[] checkSum = new byte[4];
CRC32 cs = new CRC32();
int lastSeq = 0;
java.io.FileOutputStream fw = new java.io.FileOutputStream(filename);
DatagramPacket packet = new DatagramPacket(buf, buf.length);
while(true){
dtgSock.receive(packet);
if(packet.getLength()!=0){
checkSum[0] = packet.getData()[packet.getLength()-4];
checkSum[1] = packet.getData()[packet.getLength()-3];
checkSum[2] = packet.getData()[packet.getLength()-2];
checkSum[3] = packet.getData()[packet.getLength()-1];
cs.reset();
cs.update(packet.getData(), 0, packet.getLength()-4);
//if für checkSummen vergleich
if((int)cs.getValue()==converter.convertByteArrayToInt(checkSum)){
seq = converter.FetchSn(packet.getData());
//if für Sequenznummern vergleich
if(converter.FetchSn(packet.getData()) != lastSeq){
fw.write(packet.getData(),1,packet.getLength()-5);
//System.out.print("*");
seqArr[0] = converter.IntegerToByte(seq);
DatagramPacket ackpacket = new DatagramPacket(seqArr, 1, packet.getAddress(), packet.getPort());
dtgSock.send(ackpacket);
lastSeq = converter.FetchSn(ackpacket.getData());
} else {
//System.out.println("duplicate...");
seqArr[0] = converter.IntegerToByte(seq);
DatagramPacket ackpacket = new DatagramPacket(seqArr, 1, packet.getAddress(), packet.getPort());
dtgSock.send(ackpacket);
lastSeq = converter.FetchSn(ackpacket.getData());
}
} else {
//System.out.println("damaged packet...");
}
} else break;
}
fw.flush();
fw.close();
dtgSock.close(); // Close the Socket
}
}
Zur Info: Ich möchte hier nicht die Lösung für mein Studium erschnorren, Das Programm wurde bereits abgenommen und ich konnte meinen Fehler tarnen.
Ich wüsste halt nur verdammt gern warum warum warum
LG und vielen Dank schon jetzt.