UDP Fehlerbehandlung

spitzname

Mitglied
Hallo, unten habe ich Codes für Anwendung der Clientseite und der Serverseite aufgeschrieben. Leider habe ich schwierigkeiten meine Ideen zu Fehlerbehandlung bei UDP Datenübertragung in Java Code umzustezen und würde mich über Tipps freuen.

Folgende Fehler sollen behandelt werden:
-Paketverlust
-Falsche Datenübertragung

Zeit Messen:
-Transferzeit messen

mein Ansatz zu Paketverlust:
Das erste bit des Pakets wird für die Sequenznummer reserviert, diese wird dann mit dem
Paket mitgeschickt. Erst wenn die Sequenznummer auf der Sender- und
Empfängerseite übereinstimmt, kann ein weiteres Paket verschickt werden, sonst
soll das erste Paket nochmal verschickt werden.

Bitfehlerrate:
Die CRC-Werte werden auf der Sender und Empfänger Seite ausgerechnet und
miteinander verglichen. Wenn beide Werte übereinstimmen, dann ist der
Rahmen unverfälscht angekommen.

Transferzeit:
Um die Transferzeit zu messen, wird vor dem Absenden des Rahmens ein Timer
gesetzt, der die aktuelle Zeit speichert. Beim erfolgreichen Ankommen des
Rahmens speichert der zweite Timer die aktuelle Zeit. Die Differenz der beiden
Zeiten ist dann die Transferzeit des gesendeten Rahmens.

Server
Java:
 public class FileTransferServer {


    public static void main(String args[]) throws Exception{
        // Arguments: port & filename
        int s = 12345;
        String filename = "sink.txt";
	    // Open datagramm socket
	    javax.net.DatagramSocket dtgSock;
        dtgSock = new javax.net.DatagramSocket(s);

        byte[] buf = new byte[5000];
	    java.io.FileOutputStream fw = new java.io.FileOutputStream(filename);
	    DatagramPacket packet = new DatagramPacket(buf, buf.length);
      

	    while (true){
                
		    dtgSock.receive(packet);
		    System.out.print("*");
             
                    // if receive an empty packet will indicate end of file
		    if (packet.getLength()==0) break;
   
            fw.write(packet.getData(),0,packet.getLength());		

	    }

	fw.flush();
	fw.close();
        
	dtgSock.close();	// Close the Socket
        
    }
}


Client
Java:
import java.net.*; // we use Sockets
import java.util.zip.*;

public class FileTransferClient {


    public static void main(String args[]) throws Exception{
   
        String srvName = "localhost";
        int srvPort = 12345;
        String filename = "source.txt";

	    // Open datagramm socket
	    javax.net.DatagramSocket dtgSock;
        dtgSock = new javax.net.DatagramSocket();
        InetSocketAddress srvSockAddr = new InetSocketAddress(srvName, srvPort);
        dtgSock.connect(srvSockAddr);

        byte[] buf = new byte[5];

	    java.io.FileInputStream fr = new java.io.FileInputStream(filename);

	    int len; // number of bytes written from the file

	    while ((len=fr.read(buf,0,buf.length))!= -1){

	        DatagramPacket packet = new DatagramPacket(buf, len);              
        	dtgSock.send(packet);
	        System.out.print("*");
            Thread.sleep(100);
         
	    }

	// 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

    }
}

Danke im voraus

Gruß
 
Zuletzt bearbeitet:

ice-breaker

Top Contributor

spitzname

Mitglied
Erstmal danke für die Antwort, es muss leider erstmal UDP sein, da ich dieses Thema verstehen will bevor ich zu TCP wechsle, dieses Thema kommt auch noch dran.

Es wird Simuliert, dass die Bitübertragungsschicht Rahmen verfälscht werden und dafür soll eine Lösung gefunden werden.

Würde mich weiterhin über Tipps freuen.

Lg
 
Zuletzt bearbeitet:

HoaX

Top Contributor
Transferzeit:
Um die Transferzeit zu messen, wird vor dem Absenden des Rahmens ein Timer
gesetzt, der die aktuelle Zeit speichert. Beim erfolgreichen Ankommen des
Rahmens speichert der zweite Timer die aktuelle Zeit. Die Differenz der beiden
Zeiten ist dann die Transferzeit des gesendeten Rahmens.

Wirst du so nicht hinbekommen, denn welche zwei Uhren laufen schon synchron?
 

ice-breaker

Top Contributor

spitzname

Mitglied
mach es wie das Ping-Kommando.
Sende 1 Paket zu der Gegenseite, dieser muss wieder antworten. Die Zeit für 1 Paket ist dann ~ Gesamtzeit/2

danke für den Tipp.


natürlich kannst du eine Sicherungsschicht (garantierte Übertragung) auf UDP bauen.

Ok, also um den Paketverlust zuvermeiden fügt man jedem versendeten Paket eine Sequenznummer hinzu.
Das erste bit des Pakets wird für die Sequenznummer reserviert, diese wird dann mit dem
Paket mitgeschickt. Erst wenn die Sequenznummer auf der Sender- und
Empfängerseite übereinstimmt, kann ein weiteres Paket verschickt werden, sonst
soll das erste Paket nochmal verschickt werden.

Also so: Im Clientcode im Main :
Java:
while ((len=fr.read(buf,1,buf.length-1)+1)!= -1){
 
            
            DatagramPacket packet = new DatagramPacket(buf, len);
            //die Sequenznr. wird am Anfang des Rahmens eingefügt
            buf[0] = ++paketzaehler[0]; 
            //Paket wird versendet
            dtgSock.send(packet);
            Thread.sleep(100);

             //auf eine Antwort warten
            try{
            dtgSock.setSoTimeout(500); //Timeout setzen 
            DatagramPacket recievepacket = new DatagramPacket(ack, ack.length);
            dtgSock.receive(recievepacket);     // blocking!!!         
            
            }  catch(java.io.InterruptedIOException ex){
               continue; //wenn der Timeout abgelaufen, dann noch mal senden
               }
         
        }

Server
Java:
while (true){
             // if receive an empty packet will indicate end of file
            if (packet.getLength()==0) break;
            ++paketzaehler[0];
            dtgSock.setSoTimeout(0);
            dtgSock.receive(packet);
            if(buf[0] == paketzaehler[0]){
            i++;
            System.out.print("\nEs wurden soviele Pakete empfangen: "+ i);
            fw.write(packet.getData(),1,packet.getLength()-1);
            DatagramPacket rpacket = new DatagramPacket(antw, antw.length);
            dtgSock.send(rpacket);
            } else breack;   
 
        }


Das Programm funktioniert aber leider nicht wie gewünscht wo liegt mein Fehler, würde mich über Tipps freuen.

Lg
 

Neue Themen


Oben