Socket Was muss man bei Sockets beachten?

Bizarrus

Bekanntes Mitglied
Hallo =)

Ich bin gerade dabei ein bisschen mit Java, MySQL und eine Socketverbindung ein bisschen herumzufummeln.

Generell hätte ich die Frage was ich dabei beachten muss.

Habe bereits schon eine art Server sowie Client erstellt was auch funktioniert.
Habe jezt noch ein bissl den Quelltext erweitert.

Der Server besizt nun eine MySQL Verbindung, beide Seiten sollen via "Strings" bzw "selbstgebasteltem Protokoll "kommunizieren".


Hier haben wir mal ein Beispiel:
Der Client verbindet sich auf dem Server und sendet folgende Line:
l\0Test\0Test
(Habe hierraus eine art "Login" gebastelt)
l\0Benutzername\0Passwort

Diese 3 "Parameter" im String sind relevant.
Das erste Zeichen (kleines L) bezeichnet diesen String als "Login-String" mit beigefügtem Benutzernamen und Passwort.

Der Server verarbeitet diesen String weiter (Prüft die dort beigefügten benutzerdaten, die in einer MySQL DB gespeichert sind) und gibt darauf eine Antwort:
l\0Test\0true
oder
l\0Test\0false

Hier gibt der Server an den Clienten den "Login-String" zurück und sagt das dieser Benutzer entweder angemeldet wurde (true) oder die daten nicht stimmen (false)

So. Funktionieren tut alles einwandfrei (Vielleicht kann man dies ja noch etwas verbessern)

Jezt tritt aber ein kleines problem auf, wo ich noch nicht so recht weiter weiß:

Nachdem der "Login-Token" versendet bzw Empfangen wurde, soll ein weiterer String versendet & empfangen werden ...

Habe hierbei das Gleiche verfahren angewendet, was aber nicht funktioniert. er gibt immernoch den "Login-Token" aus.

Jezt wäre hier meine erste Frage wichtig "Was muss ich bei Socket-Verbindungen beachten?".

Mittels output.println(String); bzw input.println(String); Sende bzw emfange ich die einzelnen Strings, die vom Clienten bzw Server Versendet wurden.

Was mache ich, wenn bereits einmal schon empfangen bzw versendet wurde?
Muss ich noch ein \n für "Neue Zeile" dranhängen (beim versenden)? Oder muss ich das in eine art "Buffer" bzw "cache" alles abfragen?
Oder muss ich da irgendetwas "zurücksetzen"? (Kann ja sein, das der Server sagt "So, ich habe was empfangen, um was neues zu empfangen muss ich das alte weglegen".
 
ein beliebter Fehler ist, mehrfach Streams auf den Input-/ OutputStream des Sockets zu setzen,
z.B. bei jedem Senden einen neuen BufferedWriter aufzumachen usw., das möglichst vermeiden,

ansonsten kann man es eigentlich nur richtig machen oder einen Fehler einbauen, aber wie soll man das von außen erkennen?
warum Login zweimal gesendet wird oder was auch immer ist sicherlich in deinem konkreten Code begründet,
ohne diesen wird man dazu wenig sagen können

edit:
ach doch noch zwei Standardhinweise:

flush() verwenden wenn Buffer im Spiel sind, sonst wird evtl. nicht gesendet,

und wenn mit readLine() gelesen wird, dann zwingend \n senden, ohne Zeilenumbruch ist eine Zeile nie zu Ende
 
Was schon gesagt wurde,
wichtig ist die flush() - methode,
damit sagst du deinem PrintWriter "fertig in einen Stream umgewandelt" (ich glaube ohne geht das garnicht)

persönlich finde ich die variante eine eigene Art Protokoll zu verwenden gut,
ich selber verwende das teilweise genauso.
Was da im hintergrund versendet wird bleibt eben transparent für die anwender

Versuch doch mal entweder direkt nach dem ersten Senden eine zweite verbindung aufzubauen
um einen zweiten String zu versenden.
Oder via anderen operatoren (+,AND, was auch immer) eine art Suffix anzuhängen
die der Server über Sting.Split auseinanderpflückt und anahnd der zusätzlichen info
weiterarbeitet

z.B. l/0Test/0Test+ADMINLOGIN

das wäre eine zusätzliche information zum Login, dass es sich hierbei um einen Admin handelt oder whatever.
Der Server muss die Strings dann (in diesem Beispiel) beim "+" trennen

wäre so ne Idee...
 
ich persönlich würde ein eigenes Protokoll komplett eigen implementieren. Man könnte z.B. das Erste Byte als als Command ID aufbauen. Anhand der Commandid weiß man dann was man aus zu lesen hat. Zur späteren überprüfung könnte man direkt nach der Commandid die gesamtlänge des Commands anhängen. Damit kann man beim Empfangen eines Commands warten bis der Command in der Gesamtheit da ist, bevor man es auswertet.
z.b. könnte ein Login Command so aussehen: 0x01,length,<String>,<String>
anhand des 0x01 erkennt man das es ein login command ist, dann ließt man die Länge aus und wartet bis length bytes im Puffer sind, wenn die Daten alle Da sind decodiert man den Puffer und ließt die beiden Strings aus. Wenn man die command-Ids gut definiert kann man unter verwendung von Klassen sehr schnell das Protkoll erweitern und nutzen.
 
Warum immer das Protokoll neu erfinden? Warum nicht eine RPC Technik einsetzen?

Spring RPC, RMI, SIMON, ....



- Alex
 
Das frage ich mich manchmal auch, aber bei gewissen Sachen ist es schon sinnvoll was eigenes zu machen. Vor allem wenn man den Netzwerkstack noch von hand analysieren können will.
 
sagt jemand der SIMON neu erfunden hat 😉

Text ist auch immer besser, wenn die Gegenseite nicht Java spricht
 
Hab mir gerade mal durchgelesen was RMI und RPC ist... klingt sehr gut soweit...
Wenn man größere Projekte in Angriff nimm sind diese verfahren sicher von Vorteil 🙂
 
Wenn man größere Projekte in Angriff nimm sind diese verfahren sicher von Vorteil 🙂

Das ist doch unlogisch. Wenn ich ein kleines Projekt mache und dafür die meiste Arbeit in eine selbstgefrickelte Kommunikation stecke, die sicher mehr Haken und Ösen hat als ein Schnürschuh, dann habe ich wohl mit Zitronen gehandelt. Du ahnst noch gar nicht, was du dir für Probleme einhandeln kannst, die alle schon (mit einem fertigen Protokoll und einer passenden API) gelöst sind.

Als "Testprojekt", um was zu lernen, ok.

Sonst: ob groß oder klein, es ist selten von Vorteil das Rad ohne Mehrwert neu zu erfinden! Ein Projekt wird nicht gebaut und bleibt dann stehen. Es wird leben, sich entwickeln und verändern. Die Wartbarkeit von solchen Produkten ist in der Regel nicht vorhanden oder nicht bezahlbar.
 
Geb ich dir voll und ganz recht aber ich denke für den Hobby-Programmierer würde es dennoch reichen...
Werde mich die tage mal an die RMI - Methodik setzen und schauen was für möglichkeiten einem da offen stehen.
 

Zurück
Oben