Objekte über DatagramSocket versenden

Status
Nicht offen für weitere Antworten.

paedubucher

Aktives Mitglied
Hallo allerseits

Ich schreibe eine kleine Chat-Applikation um mich etwas in die Netzwerk-, Multithreading- und GUI-Programmierung einzuarbeiten. Beim Netzwerkteil habe ich mich für DatagramSockets, also UDP-Packages, entschieden.

Nun kann ich einem UDP-Package (DatagramPackage) immer einen Datenbuffen als byte-Array mitgeben. Ich möchte aber nicht nur eine Nachricht, sondern auch Informationen wie der Absender (ein frei wählbarer Name, nicht die Absender-Adresse) mitgeben können. Natürlich könnte ich einen strukturierten String verschicken, diesen muss ich aber zuerst verketten und beim Empfänger wieder zerschnippeln. Das gehört IMHO nicht in ein Java-Programm, das sollte man doch bestimmt objektorientiert lösen können, oder?

Nun habe ich daran gedacht, eine Klasse Namens 'Message' oder etwas in der Art zu erstellen, welche den Absendernamen, das Absendedatum und natürlich die Nachricht enthält... vielleicht kommt ja später noch etwas dazu. Kann ich die Klasse irgendwie serialisieren, sodass ich einen String erhalte, aus dem man auf der anderen Seite wieder ein Objekt zusammenschustern kann? Ich habe etwas gesucht und zur Serialisierung nur Beispiele gefunden, wo ein Objekt mit einem Object-Irgendwas-Stream auf die Festplatte geschrieben und danach wieder gelesen wird. Kann ich das statt auf die Fesplatte irgendwie in einen String hineinschreiben?

Ist Serialisierung überhaupt der richtige Weg?

Bitte klärt mich auf...

Danke & Gruss

Patrick
 
Servus 🙂

der Post von paedubucher ist zwar schon sehr lange her, aber da ich mich gerade das gleiche Frage pushe ich einfach mal den Thread. Vielleicht antwortet ja mal jemand 😀

Gruß
cowabunga
 
in ObjectOutoutStream kann, wenn nicht direkt in einen UDP-Stream, in einen ByteArrayOutputStream münden, der am Ende ein byte[] draus macht,

dieses byte[] wird man doch wohl versenden können, oder notfalls in String umwandeln,
auf der Gegenseite dann wieder zu byte[], ByteArrayInputStream, ObjectInputStream
 
So, habs mal implementiert. Hier der Code-Ausschnitt:

Server:
Code:
		DatagramPacket paket = new DatagramPacket(new byte[length], length);
		new DatagramSocket(1234).receive(paket);

		Message message = (Message) new ObjectInputStream(new ByteInputStream(
				paket.getData(), length)).readObject();

Client:
Code:
		ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
		new ObjectOutputStream(byteStream).writeObject(message);

		new DatagramSocket().send(new DatagramPacket(byteStream.toByteArray(),
				byteStream.toByteArray().length, InetAddress
				.getByName("localhost"), 1234));

Auf den Code der Message-Klasse hab ich mal verzichtet. Das einzige was zu beachten ist, ist eigendlich dass die Klasse serializeable ist. Ausserdem darf die Message nicht zu groß sein, da sie sonst nicht in EINEM Packet verschickt werden kann...

cowabunga! 😀
 
hallo,
wie sichert man ab, ob die message wirklich angekommen ist? könnte man noch ACKs einbauen?lg
 
Auf den Code der Message-Klasse hab ich mal verzichtet. Das einzige was zu beachten ist, ist eigendlich dass die Klasse serializeable ist. Ausserdem darf die Message nicht zu groß sein, da sie sonst nicht in EINEM Packet verschickt werden kann...

cowabunga! 😀

Was is denn die maximale größe für ein Packet?
Was is wenn das Packet doch größer is?
Wird das automatisch aufgeteilt oder Exception?​
Was is bei dem code bsp oben bitte length beim Client?
Weil, wenn ich die nich genau angebe, bekomme ich keine reaktion. Kann man das nich allgemeiner lösen?​
 
Zuletzt bearbeitet:
Kann man das nich allgemeiner lösen?[/INDENT]

Verwende TCP statt UDP. Für einen simplen Chat ist das x-mal einfacher. Allein schon die gesicherte Zustellung und Reihenfolge der Pakete ist bei TCP von Vorteil.

UDP würd ich nur für Realtime-Informationen wie Audio und Video nutzen.
 
Weiso kramt ihr einen Thread aus der über ein halbes Jahr alt ist? Naja, jedenfalls kann es auch passieren dass das Paket unterwegs von einem Router gesplittet wird, nicht nur lokal, man kann also nie wirklich sagen wie groß ein Paket maximal sein darf.
 
Es geht mir weniger um das "Is das Sinnig?" es geht mir ums verstehen, gebrauchen, anwenden. Im mom will ich garkeine sinnigen kompletten/komplexe progs schreiben sondern einfach mal n wenig rum probieren un schaun wie ich dinge im netzwerk mache. (kommt bei mir innem monat inner uni dran un ich bin neugierig) 😳

Un um den folge zu leisten,
mir kommt grad in den sinn dasset dabei nur drum geht wie groß das array is. Für das senden macht das doch eig keinen unterschied weil der router ja zusehn muss wie er das heil rüber bekommt?!


Weiso kramt ihr einen Thread aus der über ein halbes Jahr alt ist? Naja, jedenfalls kann es auch passieren dass das Paket unterwegs von einem Router gesplittet wird, nicht nur lokal, man kann also nie wirklich sagen wie groß ein Paket maximal sein darf.

1. Da gebraucht man die SuFu un dann wird immerno gemeckert... :autsch:
2. Folglich spielt es keine rolle wie groß ich ein paket mache weils eh zerstückelt wird?
 
. Für das senden macht das doch eig keinen unterschied weil der router ja zusehn muss wie er das heil rüber bekommt?!

Deine Frage impliziert dass der Router sich um die korrekte übertrragung kümmert. Dem ist nicht so. Der Router schickts halt. Ihm ist es völlig schnuppe ob er's selbst fragmentiert (wieso auch immer), oder ob's verloren geht.

Um das "heil rüber bekommen" musst du selbst mit einem passenden Protokoll sorgen.

2. Folglich spielt es keine rolle wie groß ich ein paket mache weils eh zerstückelt wird?

".. zerstückelt werden kann". Korrekt. Du musst dich selbst drum kümmern dass man mit den Daten die ankommen noch etwas anfangen kann. Weil unterwegs können bei UDP

* Pakete verloren gehen
* zerstückelt werden (und dann davon teile verloren gehen)
* in einer total anderen Reihenfolge ankommen

Gibt also jede Mange Nachteile für UDP. Aber einen Vorteil hat es: Es ist schlank, und deshalb etwas schneller als TCP, weswegen es für Echtzeitübertragungen gern genommen wird da hier dann die Latenzen etc. am besten sind. Für alles andere gibt's TCP.

Mehr dazu gibts u.a. bei Wikipedia.

- Alex

- Alex
 
Das is doch mal ne antwort... 🙂

Du musst dich selbst drum kümmern dass man mit den Daten die ankommen noch etwas anfangen kann.

Dazu hab ich nu eine frage;
Ich hab gelernt das, beim verlust, das entsprechende paket nochmal gesendet wird.
Un was du nu schreibst, würde für mich heißen "ich muss schaun das alles ankommt und neu anfragen wenns nich der fall ist"
Lange Rede wenig Sinn, die pakete (vom router) muss ich noch auf vollständigkeit prüfen und in die richtige reihenfolge setzten?
 
Ich hab gelernt das, beim verlust, das entsprechende paket nochmal gesendet wird.

Bei UDP: Nein. Das erneute senden musst du über dein eigenes Protokoll "veranlassen".
bei TCP: Es gehen keine Pakete verloren. Und wenn doch kümmert sich TCP selbst drum dass das Paket nochmal geschickt wird.

Un was du nu schreibst, würde für mich heißen "ich muss schaun das alles ankommt und neu anfragen wenns nich der fall ist"

Nö, das hatte ich nicht geschrieben.

Lange Rede wenig Sinn, die pakete (vom router) muss ich noch auf vollständigkeit prüfen und in die richtige reihenfolge setzten?

Grob gesagt ja.

Da du's offensichtlich noch nicht bis Wikipedia geschafft hast:

UDP:
http://de.wikipedia.org/wiki/User_Datagram_Protocol#Eigenschaften hat gesagt.:
UDP stellt einen verbindungslosen, nicht-zuverlässigen Ü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. Eine Anwendung, die UDP nutzt, muss daher gegenüber verlorengegangenen und unsortierten Paketen unempfindlich sein oder selbst entsprechende Korrekturmaßnahmen beinhalten.

Da vor Übertragungsbeginn nicht erst eine Verbindung aufgebaut zu werden braucht, können die Partner schneller mit dem Datenaustausch beginnen. Das fällt vor allem bei Anwendungen ins Gewicht, bei denen nur kleine Datenmengen ausgetauscht werden müssen. Einfache Frage-Antwort-Protokolle wie das Domain Name System verwenden UDP, um die Netzwerkbelastung gering zu halten und damit den Datendurchsatz zu erhöhen. Ein Drei-Wege-Handshake wie bei TCP für den Aufbau der Verbindung würde unnötigen Overhead erzeugen.

Daneben bietet die ungesicherte Übertragung auch den Vorteil von geringen Übertragungsverzögerungsschwankungen: Geht bei einer TCP-Verbindung ein Paket verloren, wird es automatisch neu angefordert. Das braucht Zeit, die Übertragungsdauer kann daher schwanken, was für Multimediaanwendungen schlecht ist. Bei VoIP z. B. käme es zu plötzlichen Aussetzern, bzw. die Wiedergabepuffer müssten größer angelegt werden. Bei verbindungslosen Kommunikationsdiensten bringen verlorengegangene Pakete dagegen nicht die gesamte Übertragung ins Stocken, sondern vermindern lediglich die Qualität.

UDP übernimmt die Eigenschaften der darunterliegenden Vermittlungsschicht. Im Falle des Internet Protocols (IP) können Datenpakete maximal 65535 Bytes lang sein, wovon der IP-Header und UDP-Header insgesamt mindestens 28 Bytes belegen. UDP-Datagramme haben daher maximal 65507 Nutzdatenbytes. Solche Pakete werden jedoch von IP fragmentiert übertragen.

IP löscht Pakete etwa bei Übertragungsfehlern oder bei Überlast. Datagramme können daher fehlen. UDP bietet hierfür keine Erkennungs- oder Korrekturmechanismen, wie etwa TCP. Im Falle von mehreren möglichen Routen zum Ziel kann IP bei Bedarf neue Wege wählen. Dadurch ist es in seltenen Fällen möglich, dass später gesendete Daten früher gesendete überholen. Außerdem kann ein einmal abgesendetes Datenpaket mehrmals beim Empfänger eintreffen.

TCP:
http://de.wikipedia.org/wiki/Transmission_Control_Protocol hat gesagt.:
Im Unterschied zum verbindungslosen UDP (User Datagram Protocol) stellt TCP einen virtuellen Kanal zwischen zwei Endpunkten einer Netzverbindung (Sockets) her. Auf diesem Kanal können in beide Richtungen Daten übertragen werden. TCP setzt in den meisten Fällen auf das IP (Internet-Protokoll) auf, weshalb häufig (und oft nicht ganz korrekt) auch vom „TCP/IP-Protokoll“ die Rede ist. Es ist in Schicht 4 des OSI-Referenzmodells angesiedelt.

Aufgrund seiner vielen angenehmen Eigenschaften (Datenverluste werden erkannt und automatisch behoben, Datenübertragung ist in beiden Richtungen möglich, Netzüberlastung wird verhindert usw.) ist TCP ein sehr weit verbreitetes Protokoll zur Datenübertragung. Beispielsweise wird TCP als fast ausschließliches Transportmedium für das WWW, E-Mail und viele andere populäre Netzdienste verwendet.

Das sollte für's erste reichen ....

-Alex
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben