Kadaj Geschrieben 24. November 2012 Geschrieben 24. November 2012 Abend, ich möchte folgendes realisieren: mein UDP-Server soll Dateien von verschiedenen Clients entgegen nehmen. Dazu sollen die Pakete mit einer ID versehen werden, damit der Server auch weiß, zu welcher Datei die bytes gehören, die er grade reinbekommt. Dazu soll der Server immer, wenn er die ID 0 liest ( erstes Paket eines neuen Clients ) einen neuen Thread erstellen. Eine Möglichkeit wäre einfach einen int-Wert zu nehmen, den ich vorher als ID für die Verbindung festlege und den Namen des Threads damit versehe, in der Form: dataThread_2. Denn dann könnte ich den Thread immer ganz einfach durch seinen eindeutigen Namen aufrufen. Doch wie puzzle ich mir einen Threadnamen aus Variablen zusammen und rufe ihn auf? In der Shellprogrammierung ist ds ja ganz einfach. Die andere Möglichkeit, die mir durch den Kopf geht wäre, erst den Thread zu erstellen, sich dann seine ID zu holen und diese als ID für die Kommunikation zwischen Server und Client zu verwenden. Dann müsste ich aber bei 20 Threads einen bestimmten durch seine ID aufrufen können. Nur wie? Ich würde gern wissen, ob eine der beiden Möglichkeiten umsetzbar ist, und wenn ja, wie ich das mache. Vielleicht gibt es ja noch eine bessere bzw. saubere/performantere Lösung als Threads. Gruß Zitieren
flashpixx Geschrieben 24. November 2012 Geschrieben 24. November 2012 Der Socket identifiziert den Client, d.h. anhand des Socket weisst Du welcher Client verbunden ist Zitieren
Kadaj Geschrieben 24. November 2012 Autor Geschrieben 24. November 2012 Der Socket? der lauscht doch nur auf einem Port. Meinst du das Paket? Ehm, ja anhand der IP-Adresse im Header weiß ich das auch. Ich mach es halt über eine ID, die ganz vorn im Datenteil steht, dann kann ich auch unterscheiden, wenn mehrere Dateien von einem Client kommen. Also die Unterscheidung ist ja nicht das Problem, viel mehr wie ich mit erhaltenen Paketen gleichzeitig umgehe. Ich habe ja für jede Datei einen Dateinamen, wenn ich abwechselnd verschiedene Dateistückchen bekomme, dann würde ich die Pakete einfach an den Thread weitergeben, der die Datei bereits geöffnet hat und schon darauf warten weiter zu schreiben. Zitieren
uenetz Geschrieben 24. November 2012 Geschrieben 24. November 2012 Ich werfe mal einfach eine Idee in den Raum. Darum machst Du nicht bei jeder Socketverbindung einen eigenen Thread? Dann hast Du das Handling mit der ID gespart. Betreffend der ID: ich würde mir keine eigene ID erstellen, sondern eher die Portadresse über den die Kommunikation läuft nehmen, denn die ist auch eindeutig Zitieren
Kadaj Geschrieben 24. November 2012 Autor Geschrieben 24. November 2012 Danke, dass du mitspielst Ich kann dir aber nicht ganz folgen. Also du meinst, dass ich beim ersten lauschen auf eine Verbindung schon im ersten Thread bin? Wie soll das ohne ID funktionieren? Der UDP-Server lauscht auf genau einem Port und bekommt die Daten der verschiedenen Clients doch alle über genau diesen Port rein. Selbst wenn mein Server 3 Threads hat und alle auf verschiedenen Ports lauschen, kann mein Client doch nicht wissen auf welchem Port er senden soll, wenn nicht zuvor festgelegt. Also ich bin in Java noch recht grün hinter den Ohren, vielleicht versteh ich es ja, wenn du etwas weiter ausholst^^ Gruß Zitieren
flashpixx Geschrieben 24. November 2012 Geschrieben 24. November 2012 Nein im Normalfall hat man den Server auf einen Port gebunden, d.h. auf diesem hört der Server eingehende Nachrichten, wenn nun eine Nachricht kommt, dann teilt der Server dem Client nur einen "zufällig" gewählten Port > 1023 mit und der Client kommuniziert dann mit dem Server über diesen Port. Damit hat jeder Client seinen eigenen Port / Socket und dieser Vorgang wird in einen eigenen Thread verlagert. Zitieren
Kadaj Geschrieben 24. November 2012 Autor Geschrieben 24. November 2012 (bearbeitet) Ah, nun verstehe ich das. Das hört sich ja garnichtmal so dumm an, werd ich direkt man umsetzen. Danke euch beiden! Eine Frage aber noch dazu. Wenn ich bei sehr vielen Verbindungen immer einen Port höher gehe, dann muss ich im Fall der Fälle ja irgendwann wieder anfangen von vorne zu zählen. Wenn also der erste Port den ich vergeben habe grade eine gigantische Datei rüberschiebt, die immer noch nicht fertig ist, selbst wenn der Server schon 65000 Daten bekommen hat. Wie kann ich dann überprüfen ob der Port grade noch belegt wird? Trotzdem würde mich auch die Geschichte mit den Namen der Threads interessieren, bzw einen Aufruf über die ID. Haben die Javaentwickler dafür etwas vorgesehen? Gruß Bearbeitet 24. November 2012 von Kadaj Zitieren
flashpixx Geschrieben 24. November 2012 Geschrieben 24. November 2012 Du braucht nicht jedes mal einen neuen Port zu verwenden, ein Socket reicht. Der Server erzeugt nachdem der Client verbunden ist einen Socket in einem neuen Thread, d.h. der Client hat einen neuen Socket und der Server dazu auch, d.h. der Server kennt über das Socketobjekt den Client. Wie man nun Threading im Detail implementiert und ob man evtl dynamische Ports (neue Ports vergibt) kommt auf die Kommunikationsdetails an. Zitieren
Kadaj Geschrieben 24. November 2012 Autor Geschrieben 24. November 2012 Ja, das hatte ich schon verstanden. Ich meine aber was anderes. Der Server vergibt ja für jede eingehende Verbindung einen extra Port, damit meine ich natürlich für jede Datei, die von einem anderen Client versendet wird, bevor er diese Verbindung dann in einen extra Thread schickt. Trotzdem muss ich ja prüfen ob dieser Port grade schon von einem anderen Client in einem anderen Thread verwendet wird. Immerhin kann man ja einen mehrere Sockets mit dem selben Port erstellen. Wenn es ganz dumm kommt, dann vergibt der Server an 2 Clients den selben Port udn 2 Threads laufen über einen Port. Gruß Zitieren
flashpixx Geschrieben 24. November 2012 Geschrieben 24. November 2012 lies bitte mein vorhergehendes Post Der Server vergibt ja für jede eingehende Verbindung einen extra Port, damit meine ich natürlich für jede Datei, die von einem anderen Client versendet wird, bevor er diese Verbindung dann in einen extra Thread schickt. er kann einen neuen Port verwenden er muss es aber nicht Trotzdem muss ich ja prüfen ob dieser Port grade schon von einem anderen Client in einem anderen Thread verwendet wird. Immerhin kann man ja einen mehrere Sockets mit dem selben Port erstellen. Wenn es ganz dumm kommt, dann vergibt der Server an 2 Clients den selben Port udn 2 Threads laufen über einen Port. Du kannst einen Port verwenden und jedes Mal wenn ein Client auf einem definierten Port connected wird ein neuer Socket in einem neuen Thread erzeugt, über den die Daten ausgetauscht werden (Socket != Port), d.h. Du hast einen Masterthread laufen über den der Verbindungsaufbau statt findet, wenn nun eine Verbindung eingeht, wird ein neuer Thread erzeugt, in dem wiederum ein neuer Socket erzeugt wird. Wird der Socket geschlossen, wird der Thread beendet. Sprichwörtlich wird somit jeder Connect eines Clients über einen Thread und einen Socket realisiert. Zitieren
Kadaj Geschrieben 24. November 2012 Autor Geschrieben 24. November 2012 (bearbeitet) Ich glaub meine Problembeschreibung ist einfach zu schlecht:old Deine Erklärung dazu hatte ich beim ersten Mal verstanden. Ich möchte nur eines wissen: Angenommen mein Server hat 100 Sockets auf Port 1300 bis 1400 offen, auf denen grade Dateien übertragen werden undzwar jede in einem Thread. Nun kommt eine neue Datenübertragung von einem weiteren Client rein. Alles was ser Server machen muss ist ja nur ein neuen Port suchen und das Startpaket an den Thread übergeben. Weil dieser Thread dann einen Socket erstellt und auf einem Port lauscht, der noch nicht belegt ist, verwende ich auch keine ID mehr, denn auf diesem Port kommen ohnehin nur Pakete von diesem einen Client rein. So meintest du es doch, oder? Meine Frage bezieht sich aber auf "Server sucht sich einen freien Port", denn damit das ganze überhaupt funktioniert muss ich mir ja einen Port suchen, der von keinem anderen Socket verwenden wird. Ich würde mir nämlich einfach einen int anlegen, den ich mit 1024 initialisiere und ihn dann immer höchzählen lasse. Wenn ich also irgendwann bei Port 65535 angekommen bin und wieder bei 1024 anfange, dann möchte ich gern wissen ob mein erster Thread, der Port 1024 bekommen hatte schon mit seiner Datei fertig ist, die beispielsweise 50GB umfasst. Der Server soll also prüfen "Wird grade eine Datei auf Port 1024 übertragen". Wenn ja, dann versuch es mit 1025, wenn nein, nimm den Port und übergib das Paket mit dem Port an einen neuen Thread. Ich hoffe, ich konnte es einigermaßen verständlich beschreiben;) edit: Ich hab grad mit einem Ping-Server getestet was passieren würde, wenn ich einen Socket mit einem Port anlege, der schon von einem anderen Socket verwendet wird, allerdings TCP. In diesem Fall wird eine BindException angezeigt und das Programm stürzt ab. Das hab ich nicht gewusst. Eigentlich sagt einem Eclipse ja, wenn eine Exception nicht behandelt wurde. Ich denke, das sollte das Problem mit bereits verwendeten Ports abwenden. Vielleicht war meine Frage einfach so trivial, dass ein Javagott einfach nicht so dumm denken kann Bearbeitet 24. November 2012 von Kadaj Zitieren
flashpixx Geschrieben 24. November 2012 Geschrieben 24. November 2012 Weil dieser Thread dann einen Socket erstellt und auf einem Port lauscht Nein es findet kein Listen statt. Der Client connected, ein neuer Thread wird erzeugt. In dem Thread teilt der Server dem Client z.B. einen dynamischen Port zu, Client und Server verbinden. Server und Client kennen den Port auf dem sie sich verbinden, d.h. Du musst nicht suchen und er muss auch nicht darauf warten, ob da eine Verbindung kommt. Lass diese ganze Portsuche weg. Der Client connected, der Server erzeugt beim Connect des Clients einen neuen Thread mit einem Socket drin, d.h. Du hast eine Punkt-zu-Punkt Verbindung zwischen Server & Client über die Du Daten übertragen kannst. Gibt es einen Socketfehler oder eben die Datenübertragung ist beendet, wird der Socket geschlossen und der Thread beendet. Dynamische Portverwendung brauchst Du letztendlich nur, wenn der Server eben gewisse Anforderungen bereit stellen muss. Du braucht bei einem einfachen Serverdienst genau einen Port. Zitieren
uenetz Geschrieben 25. November 2012 Geschrieben 25. November 2012 Hier mal ein kleines Beispiel das ich gefunden habe und ich meine das passt auch gut! Ob Du mit einem Socket nun alle anstehenden Filetransfers erledigt, oder ob Du für jeden Transfer eine neue Verbindung aufbaust, ist Dir überlassen. Einfacher ist wohl die Verbindung die Verbindung bei jedem Upload neu aufzubauen. import java.io.*; import java.net.*; class UDPServer { public static void main(String args[]) throws Exception { DatagramSocket serverSocket = new DatagramSocket(9876); byte[] receiveData = new byte[1024]; byte[] sendData = new byte[1024]; while(true) { DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); serverSocket.receive(receivePacket); String sentence = new String( receivePacket.getData()); System.out.println("RECEIVED: " + sentence); InetAddress IPAddress = receivePacket.getAddress(); int port = receivePacket.getPort(); String capitalizedSentence = sentence.toUpperCase(); sendData = capitalizedSentence.getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); serverSocket.send(sendPacket); } } } Zitieren
uenetz Geschrieben 25. November 2012 Geschrieben 25. November 2012 Ich habe gerade das Einstiegsposting überflogen. Danach stellte sich mir EINE Frage: Anstatt einen UDP- Client/Server zu implementieren, wäre es da nicht einfacher die Dateien auf den FileServer zu kopieren? Man macht sich ja nicht unbedingt gerne unnötige Arbeit ... es sei denn, man will spielen/lernen *zwinker Zitieren
flashpixx Geschrieben 25. November 2012 Geschrieben 25. November 2012 User Datagram Protocol UDP stellt einen verbindungslosen, nicht-zuverlässigen und ungesicherten wie auch ungeschützten Übertragungsdienst bereit. Das bedeutet, es gibt keine Garantie, dass ein einmal gesendetes Paket auch ankommt, dass Pakete in der gleichen Reihenfolge ankommen, in der sie gesendet wurden, oder dass ein Paket nur einmal beim Empfänger eintrifft. Es gibt auch keine Gewähr dafür, dass die Daten unverfälscht oder unzugänglich für Dritte beim Empfänger eintreffen. Eine Anwendung, die UDP nutzt, muss daher gegenüber verlorengegangenen und unsortierten Paketen unempfindlich sein oder selbst entsprechende Korrekturmaßnahmen und ggfs. auch Sicherungsmaßnahmen vorsehen. Ein Datenschutz ist bei dieser offenen Kommunikation nicht möglich. Für einen Dateitransfer ist UDP somit das falsche Protokoll Zitieren
uenetz Geschrieben 25. November 2012 Geschrieben 25. November 2012 Genau flashpixx, das kommt noch hinzu *g Zitieren
Kadaj Geschrieben 25. November 2012 Autor Geschrieben 25. November 2012 (bearbeitet) Ja, da habt ihr natürlich Recht Ich muss das aber als Prüfungsvorleistung realisieren. "Datenübertragung mittels UDP und Stop and Wait". Es kommt ja noch eine crc16-Überprüfung hinzu. Das war der einzige Punkt wo ich etwas ins Grübeln gekommen bin. Der Client ist nicht das Problem, dem ist ja egal ob mein Server Threads verwendet oder nicht. Das mit den Threads und den Sockets habe ich jetzt auch verstanden, dank euch. Danke für eure Nerven Bearbeitet 25. November 2012 von Kadaj Zitieren
flashpixx Geschrieben 25. November 2012 Geschrieben 25. November 2012 Es kommt ja noch eine crc16-Überprüfung hinzu. Das nützt Dir nichts, denn es ist nicht garantiert, dass a) jedes Paket was der Client an den Server sendet überhaupt ankommt, d.h. die CRC Summe wird ggf auf dem Server eine andere sein, wie auf dem Client und die Reihenfolge der Pakete ist nicht garantiert, d.h. wenn die Pakte 1,2,3 vom Client abgesendet werden, können am Server die Pakete 2,1,3 ankommen, was dann zu einer anderen CRC Prüfsumme führt, aber c) Du kannst das überhaupt nicht prüfen, denn wenn Du die CRC Prüfsumme vom Client zum Server überträgt ist auch nicht garantiert was am Server ankommt, d.h. die CRC Prüfsumme die der Server aus seinen empfangenen Daten berechnet und die CRC Summe, die Du auf dem Client berechnest können selbst bei gleichen Daten unterschiedlich sein oder eben bei unterschiedlichen Daten gleich. Das Verhalten ist bei UDP nicht deterministisch, somit ist eine Datenübertragung per UDP fachlich völlig sinnfrei. Für Datenübertragung ist es essentiell wichtig, dass garantiert ist, dass jedes Datenpaket zwischen zwei Endpunkten ankommt und zusätzlich muss garantiert sein, dass die Reihenfolge (Ordnungsrelation) erhalten bleibt. UDP wurde primär für Datenstreams entwickelt, bei denen es keine Rolle spielt, ob ein Paket ankommt oder nicht. Ich empfehle Dir, dass Du einmal die netzwerktechnischen Grundlagen anschaust, bevor Du es versuchst etwas zu programmieren. Zitieren
Kadaj Geschrieben 25. November 2012 Autor Geschrieben 25. November 2012 crc16 dient nur dazu um Fehler durch die Übertragung zu erkennen. Die Reihenfolge ist auch kein Thema, weil wir das Stop-and-Wait-Protokoll nehmen sollen. Hat der Server ein Paket bekommen, sendet er ein Paket an den Client zurück und der Client warten mittels eines Timeouts auf dieses Paket. Läuft das Timeout ab, sendet der Client das Paket nochmal. Das nächste sendet er erst, wenn er die richtige Antwort vom Server bekommen hat. Ich empfehle Dir, dass Du einmal die netzwerktechnischen Grundlagen anschaust, bevor Du es versuchst etwas zu programmieren. Harte Worte, aber keine Angst. Ich hab mir den Netzwerkteil im Wesley-Buch durchgelesen und auch verstanden. Mir ist völlig klar, dass dieses Programm totaler Humbug ist, weil weder Stop-and-Wait, noch UDP dafür geeingnet sind, aber unser Prof will es so und wenn er nen crc16 haben will, dann bekommt er es hlat. Ob wir was sinnvolles programmieren oder nicht ist ihm dabei auch völlig egal, er will nur sehen, dass wir es können^^ Zitieren
flashpixx Geschrieben 25. November 2012 Geschrieben 25. November 2012 Die Reihenfolge ist auch kein Thema, weil wir das Stop-and-Wait-Protokoll nehmen sollen. Hat der Server ein Paket bekommen, sendet er ein Paket an den Client zurück und der Client warten mittels eines Timeouts auf dieses Paket. Nehmen wir mal den Fall an, der Client initiiert die Kommunikation, der Server erzeugt seinen Socket und bekommt das erste Paket vom Client, sendet sein Ack zurück, aber das kommt beim Client nicht. Der Client sendet dann noch einmal das gleiche Paket. Der Server kann in dieser Konstellation nicht entscheiden, ob die Daten, die er da ein zweites Mal bekommt nicht schon erhalten hat (Stichwort: Sequenznummer). Diese Duplikate können auch bei schlecht gewählten Timeouts statt finden, da Client und Server nicht synchronisiert sind. Als weiterer Punkt: UDP ist verbindungslos, d.h. wenn ein Paket gesendet wurde, hat das System keine Kenntnis von weitere Kommunikationsstruktur. Eine Datei wirst Du sicher nicht in einem einzelnen Paket unterbringen können, d.h. für den Server sind das erst mal unabhängig eingehende Pakete (Stichword: iid). Sprich wenn ich einfach UDP Pakete generiere und an Deinen Server schicke und diese zufällig mit Daten fülle, dann werde ich Deinen Dienst garantiert überfordern können, denn der Dienst verhält sich wie eine Warteschlange. Da Du jedes eingehende Paket entsprechend in eine Ordnung überführen musst und eben bei der Dateiübertragung dann in den passenden Filestream schreiben musst. Als Bsp ich sende Dir 1000 Initialisierungspakete, dass ich Dir 1000 Dateien senden möchte, Dein Server muss die Acks genieren und ich sollte dann darauf passend die Datenpakete senden, was ich aber nicht mache. Dann hat Dein Server 1000 offene Verbindungen und kann nicht entscheiden, kommen da noch Daten oder nicht. Nun initialisiere ich noch einmal 1000 neue Verbindungen.... (Stichwort Denial of Service ). Dein Dienst schreit förmlich danach ihn lahm zu legen.... Bei TCP kann der Server entscheiden, wenn noch einer gewissen Zeit keine Daten mehr rein kommen, dass er einfach die Verbindung trennt. Der Client wird dies dann gemeldet bekommen. Zitieren
Kadaj Geschrieben 25. November 2012 Autor Geschrieben 25. November 2012 Nehmen wir mal den Fall an, der Client initiiert die Kommunikation, der Server erzeugt seinen Socket und bekommt das erste Paket vom Client, sendet sein Ack zurück, aber das kommt beim Client nicht. Der Client sendet dann noch einmal das gleiche Paket. Der Server kann in dieser Konstellation nicht entscheiden, ob die Daten, die er da ein zweites Mal bekommt nicht schon erhalten hat (Stichwort: Sequenznummer). Diese Duplikate können auch bei schlecht gewählten Timeouts statt finden, da Client und Server nicht synchronisiert sind. Normaler Weise schon. Es ist ja auch meine Aufgabe, das so zu implemetieren, dass alles sauber funktioniert. Mein Server setzt nach seiner Antwort auf des Startpaket des Clients einen int-Wert zunächst auf 1, heißt, dass er für das nächste(also das erste Datenpaket) ein ack von 1 erwartet. Der Client schickt das erste Paket erst los, wenn er die Antwort des Server mit der Portnummer erhlaten hat. Dieses erste Paket hat natürlich den ack=1. Bekommt der Server das Paket setzt er seinen Wert des nächsten zu erwartenden acks auf 2 und schickt dem Client ein Paket von 6 byte( short( 2 ) + int( crc ) ). Wenn der Client das Paket bekommt, dann schickt er sein nächstes Paket mit ack 2. Der ack-Wert wird dabei immer abwechselnd auf 1 und 2 geändert, was ja kein Problem ist beim Stop-and-Wait-Protokoll. Angenommen ein Paket geht verloren, so wie du es beschrieben hast, dann bekommt mein Server ein Paket, welches er schon erhalten hat eben nochmal. Ich würde aber zunächst prüfen, ob das ack mit dem, was der Server als nächstes erwarten würde übereinstimmt. Ist das nicht der Fall, dann sendet der Server einfach nochmal das letzte Antwortpaket und ignoriert das Paket. Als weiterer Punkt: UDP ist verbindungslos, d.h. wenn ein Paket gesendet wurde, hat das System keine Kenntnis von weitere Kommunikationsstruktur. Eine Datei wirst Du sicher nicht in einem einzelnen Paket unterbringen können, d.h. für den Server sind das erst mal unabhängig eingehende Pakete (Stichword: iid). Sprich wenn ich einfach UDP Pakete generiere und an Deinen Server schicke und diese zufällig mit Daten fülle, dann werde ich Deinen Dienst garantiert überfordern können, denn der Dienst verhält sich wie eine Warteschlange. Da Du jedes eingehende Paket entsprechend in eine Ordnung überführen musst und eben bei der Dateiübertragung dann in den passenden Filestream schreiben musst. Aber nicht, wenn mein Server sich erst die letzten 4 bytes holt, die der crc16-Prüfung des Clients entsprechen und die restlichen Daten dann selbst mit seiner eigenen crc16-Tabelle überprüft. Stimmte der Wert nicht überein, was bei zufälligen Paketen auf jeden Fall der Fall sein wird, dann ignoriert er das Paket Als Bsp ich sende Dir 1000 Initialisierungspakete, dass ich Dir 1000 Dateien senden möchte, Dein Server muss die Acks genieren und ich sollte dann darauf passend die Datenpakete senden, was ich aber nicht mache. Dann hat Dein Server 1000 offene Verbindungen und kann nicht entscheiden, kommen da noch Daten oder nicht. Nun initialisiere ich noch einmal 1000 neue Verbindungen.... (Stichwort Denial of Service ). Dein Dienst schreit förmlich danach ihn lahm zu legen.... Bei TCP kann der Server entscheiden, wenn noch einer gewissen Zeit keine Daten mehr rein kommen, dass er einfach die Verbindung trennt. Der Client wird dies dann gemeldet bekommen. Ganz so schlimm ist es dann doch nicht. Mein Server verwendet ein Timeout von ca 10 Sekunden in seinen Threads. Entweder er bekommt ein Paket, oder die 10 Sekunden sind um. In diesem Fall gehe ich einfach davon aus, dass der Client nichts mehr sendet. Also mir ist schon klar, dass es am Ende ein Programm ist, dass man mal geschrieben hat um ein wenig Sockets zu üben und dann nie wieder verwendet. Ich hätte auch lieber TCP genommen und anstelle von Stop-and-Wait einen Puffer von ca 10 Paketen verwendet, aber die Aufgabe unseres Profs schreibt es so vor Zitieren
flashpixx Geschrieben 25. November 2012 Geschrieben 25. November 2012 Aber nicht, wenn mein Server sich erst die letzten 4 bytes holt, die der crc16-Prüfung des Clients entsprechen und die restlichen Daten dann selbst mit seiner eigenen crc16-Tabelle überprüft. Stimmte der Wert nicht überein, was bei zufälligen Paketen auf jeden Fall der Fall sein wird, dann ignoriert er das Paket Nein, die CRC Summe bezieht sich auf den Inhalt des Paketes ( User Datagram Protocol ), d.h. Du kannst damit Prüfen, ob das Paket korrekt übertragen wurde. Du kannst aber nicht entscheiden, ob die gesamte Datenübertragung korrekt ist. Sich sende Dir 1,2,3 + Prüfsumme, d.h. 4 Pakete, wenn nun aber nur 3 Pakete ankommen, dann kannst Du nicht entscheiden, ob das letzte Paket ein Datenpaket oder ein Prüfsummenpaket ist. Wenn ich annehme, dass alle 4 Pakete eingehen z.B. in der Reihenfolge 1,Prüfsumme,2,3 dann würdest Du annehmen, dass das letzte Paket das Prüfsummenpaket ist, wäre es aber nicht. Selbst wenn Du alle Pakete bekommst und Du die Prüfsumme bildet und die Prüfsumme falsch ist, kannst Du nicht sagen, welches Paket Du vom Client noch einmal anfordern musst, denn es existiert keine Ordnung in den Paketen, d.h. wenn die Prüfsumme inkorrekt ist, musst Du die ganze Übertragung noch einmal durchführen und das ist extrem ineffizient. Bei TCP weisst Du anhand der Sequenznummer welches Paket noch einmal angefordert werden muss. Ganz so schlimm ist es dann doch nicht. Mein Server verwendet ein Timeout von ca 10 Sekunden in seinen Threads. Entweder er bekommt ein Paket, oder die 10 Sekunden sind um. In diesem Fall gehe ich einfach davon aus, dass der Client nichts mehr sendet. Und was passiert, wenn der Client trotzdem sendet !? Ein Paket wird eingehen, sprich in diesem Fall wird bei Dir ein neuer Thread erzeugt und gedanklich ein neuer Clientzugriff generiert, in diesem Fall ist das Problem aber, dass die Daten die ankommen nicht zugeordnet werden können. Mir ist das Prinzip der Übung schon klar, nur solltest Du evtl mal mit Deinem Prof darüber sprechen. Zitieren
Kadaj Geschrieben 25. November 2012 Autor Geschrieben 25. November 2012 Sich sende Dir 1,2,3 + Prüfsumme, d.h. 4 Pakete, wenn nun aber nur 3 Pakete ankommen, dann kannst Du nicht entscheiden, ob das letzte Paket ein Datenpaket oder ein Prüfsummenpaket ist. Wenn ich annehme, dass alle 4 Pakete eingehen z.B. in der Reihenfolge 1,Prüfsumme,2,3 dann würdest Du annehmen, dass das letzte Paket das Prüfsummenpaket ist, wäre es aber nicht. Achso meinst du das. Ich sende ein einziges Paket, bestehend aus einem byte, welches beispielsweise 1000 byte groß ist. DIe ersten 2 byte sind die Paketnummer, dann kommen Daten und die letzten 4 byte sind die crc-Prüfsumme. Ich hol mir also einfach die Prüfsumme und überprüfe den Rest des byte-Arrays selbst nochmal mit crc. Es ist also nur ein Paket, was ich sende Selbst wenn Du alle Pakete bekommst und Du die Prüfsumme bildet und die Prüfsumme falsch ist, kannst Du nicht sagen, welches Paket Du vom Client noch einmal anfordern musst, denn es existiert keine Ordnung in den Paketen, d.h. wenn die Prüfsumme inkorrekt ist, musst Du die ganze Übertragung noch einmal durchführen und das ist extrem ineffizient. Bei TCP weisst Du anhand der Sequenznummer welches Paket noch einmal angefordert werden muss. Da ich nur ein Paket sende und immer erst auf die Bestätigung warte, ist das kein Problem. Und was passiert, wenn der Client trotzdem sendet !? Ein Paket wird eingehen, sprich in diesem Fall wird bei Dir ein neuer Thread erzeugt und gedanklich ein neuer Clientzugriff generiert, in diesem Fall ist das Problem aber, dass die Daten die ankommen nicht zugeordnet werden können. Ja, das stimmt. Wenn der Client 10 Sekunden nicht sendet, dann hat er halt Pech. Das ist eine Tatsache, die man nur mit TCP handeln kann. In diesem Fall wird der Client eben eine Exception, die ich extra behandeln muss. Aber wie du auch schon gesagt hast, die andere Seite wäre, die Sockets einfach offen zu lassen. Da nehm ich lieber in Kauf, dass der Client sich beenden muss. Mir ist das Prinzip der Übung schon klar, nur solltest Du evtl mal mit Deinem Prof darüber sprechen. Ja, aber erst, wenn ich das Modul bestanden habe Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.