Mir gehts auch nicht wirklichum das Protokoll an sich, sonern, was ich in Java einfach umsetzen kann: Eine Implementierung eines Datenaustauschs auf Basis von lesbaren Strings wäre schon ausreichend.
öhm ... das is ganz einfach ...
einfach ne verbindung aufbauen und dann einfach mit den streams des sockets arbeiten
n einfaches beispiel wäre z.B. das der server über Runtime.getRumtime().exec() ne CMD oder n TERMINAL startet und dann an den socket hängt ...
mit dem client machst du das genau umgekehrt ... da hängst du den clienten an die console und leitest die eingaben durch den socket zum server weiter ... der führt die dann auf seiner konsole aus und schickt das ergebnis via socket zu dir zurück ... das kannst du dann einfach ausgeben lassen ...
ich weis ... klingt wahrscheinlich ziemlich dumm dieses beispiel ... aber abgesehen von verschlüsselung und authetifizierung ist es im grunde das was zum beispiel bei SSH abläuft ..
wie gesagt ... wäre jetzt so das einfachste beispiel ...
Nur als Bsp (nich ganz logisch, weil Teile des Programms fehlen):
Ich möche das aktuelle Verzeichnis wecheln können und im aktuellen Verzeichnis Dateien und Verzeichnise auflisten (und zurückgeben) lassen können. Es sollen Dateien gelöscht werden und andere Aktionen mit ausgeführt werden können.
Soweit klingt das fast wie der Log einer Konsole. Die anderen Befehle werden ungefähr den selben Komplexitätsgrad haben.
ähm ... dieses beispiel würde ich unter dem sammelbegriff DATENVERWALTUNG abstempeln
abgesehen davon das es sowas mitlerweile eine million mal implementiert gibt *auch als netzwerk-variante *sie PowerShell *win* oder SSH *unix** würde ich bei sowas immer abstrakt beliben und versuchen so viel wie möglich an das host-system zu delegieren ... spart dir ne menge code
Verstehe ich das richtig, dass du der Meinung bist, wenn ich über einen StringTokenizer gehe, dass dann eine manuelle Auswertung der übertargenen Daten von beiden Seiten aus am effektivsten/einfachsten ist?
solltest du dich wirklich entschließen ein eigenes protokoll zu erarbeiten würde ich sagen das StringTonkenizer auf jeden fall die einfachste variante ist ... effektiv ... darüber lässt sich streiten
gucken wir uns doch mal den HTTP-Client von Apache etwas näher an ...
wenn du das ding im source mal völlig auseinander nimmst wirst du feststellen das du an einem punkt ankommen wirst wo genau solche dinge getan werden z.B. die zerlegung in HTTP-STATUS *erste zeile* HTTP-Header *standardisiert* sog. X-Header *nicht genormte header welche durch module *z.B. PHP - X-Powered-by: PHP* gesetz werden um clienten die möglichkeit zu geben erweiterte informationen zum server zu erhalten* und letzendlich dem content
grade die header werden mit StringTokenizer und der gleichen auseinander genommen *ggf auch mit regular expressions geparsed* und mit konstanten verglichen um zu überprüfen was denn genau drin steht ...
das ganze wird dann schön aufbereitet und dem user mit einer vielzahl von methoden zugänglich gemacht ...
genau das ist es aber was eine gute protokoll-implementation ausmacht ...
na klar ist jede implementation nur so gut wie das protokoll selbst auf der diese läuft
um jetzt aber nich wieder so n kilometer an text hier hin zu klatschen
ein einfaches protokoll zur datenverwaltung wäre zum bleistift folgendes
erstmal die definierten befehle , wie
DELETE
MOVE
COPY
NEW
etc ...
dann die syntax ... also wie diese befehle zusammengesetz werden müssen und wie die parameter zu übergeben sind ... z.b.
<COMMAND> <OPTIONS> <FILE>
oder auch sowas *was sich im parsen nachher einfacher macht*
"<COMMAND>"|"-o<OPTION1>=<VALUE1>[&<OPTION2>=<VALUE2>]"|"<FILE>"
hier ist schon die trennung mit vorgegeben ...
wenn du in einer normalen konsole bist ist der trenner meist <LEERZEICHEN> *oder hex 0x20*
wenn du das ganze aber nun über streams oder pipes schickst dann interpretieren diese manchmal das leerzeichen als terminator oder fehler ... daher ist es besser wenn man wirklich alles zusammen in einem zusammhängenden string verschickt
die anführungszeichen sowie die eindeutigen trenner zwischen einzelnen segmenten *z.B. zwischen den optionen* ermöglichem dem parser nachher gezielt das kommando in seine bestandteile zu zerlegen
dessweiteren wird von den meisten modernen interpretern etwas zwischen zwei anführungszeichen als zusammenhängende einheit betrachtet womit diese nicht z.b. an leerzeichen oder anderen verbindungsspezifischen sondernzeichen *in unserem fall das | zur trennung zwischen COMMAND , OPTION und FILE* ignoriert werden
das wäre dann schon erstmal die eine hälfte des protokolls ... die sog. COMMANDOS ...
weiter gehts mit den folgen ... die sog. RESPONSES ...
jedes commando was du ausführst hat auch rückgaben ... *zumindest sollte dies so sein*
diese müssen natürlich auch wieder verarbeitet und verschickt werden ...
und jetzt wird es in meinem kleinen beispiel schon haarig ...
mein protokoll sieht so aus
"<COMMAND>"|"<OPTIONS>"|"<FILE>"
um jetzt bei einer antwort meinem protokoll treu zu bleiben brauchen wir als COMMAND ein festes keyword das signalisiert : achtung ! das hier ist ne antwort auf ein command ... *auf welches ist hier noch egal*
nehmen wir dafür als COMMAND ganz eifnach mal "RESPONSE"
allerdings haben wir jetzt keine datei mehr auf die wir uns beziehen können ...
also setzen wir diesen wert einfach auf "NULL"
also sieht eine antwort IMMER ... und wirklich IMMER in jedem fall .. so aus
"RESPONSE"|"<OPTIONS>"|"NULL"
hier ist jetzt der unterschied zwischen NULL und "NULL" zu beachten ...
während "NULL" ein string ist der dann auch genau so auftaucht ist NULL einfach das fehlen von informationen / pointern / daten / etc
also muss als weitere protokoll-spezifikation festgelegt werden : ALLES IST EIN STRING ...
der parser muss nachher natürlich entsprechend gebastelt werden das er entweder dieses "NULL" ignoriert oder als sicherheitsmerkmal nimmt um zu prüfen ob es ein gültiger RESPONSE ist ... dann laut spezifikation *siehe oben* muss FILE in einem RESPONSE den string "NULL" enthalten
die eigentlich antwort müssen wird jetzt verpacken und in OPTIONS reinquetschen ...
dafür haben ich oben schon extra dieses kontrukt hier angeführt
"-o<OPTION1>=<VALUE1>[&<OPTION2>=<VALUE2>]"
erklärung
die anführungszeichen sind wieder vom protokoll vorgeschrieben ... diese dienen zusammen mit dem | zeichen als trenner
das -o leitet den OPTION-tag ein ...
da es auch COMMANDOS gibt die als optionen halt auch mal NICHTS haben können können wir hier bandbreite sparen in dem bei solchen fällen nach dem COMMAND gleich das FILE kommt ...
um dies festzustellen kann man einmal die möglichkeit wählen das man prüft ob es nur 2 elemente *COMMAND|FILE* oder doch alle 3 elemente *COMMAND|OPTION|FILE* gibt
zusätzlich kann man zur sicherheit noch auf das vorhandensein von -o prüfen ...
so kann man z.B. client-seitig schon fest stellen ob das kommando syntaktisch korrekt ist bevor man sinnlosen overhead erzeugt in dem man dieses falsche kommando erst zum server schickt der dann erst feststellen muss ob das kommando valid ist ...
das mag zwar bei 3 oder 4 kommandos noch keinen unterschied machen ... bei ein paar 10'000 wird man sehen wie anfällig es ist wenn man die gesamten zeiten zusammen rechnet
zurück zum thema
also aufbau für OPTION wählen wir folgendes model
"-oCMD=<Kommando, welches diesen RESPONSE ausgelöst hat>&STAT=<Status ; kann mit numerischen werten oder weiteren kommandos belegt werden>[&<DATA>]"
der letzte in eckigen klammernstehende teil ist optional und kann z.B. für Base64-kodierte binär-daten *ja ... man kann binär-daten in strings packen wenn diese durch Base64 in darstellbare zeichen umgewandelt wurden* oder ausführlichen fehlermeldungen falls der fehler beim server liegt und der client über den mitgeteilten status nicht genug informationen hätte *müsste man server-seitig lösen das immer genug informationen vorhanden sind*
damit wären wir erstmal mit dem protokoll an sich selbst soweit durch ...
alle spezifikationen die benöigt werden sind gegeben ...
wenden wir uns der aufbereitung der daten zu
wenn nun einer der beiden ein solches kommando bekommt .. sei es angefordert oder nicht *z.B. durch erreichen von TimeOut's sendet der server dem client ein PING welches er bestätigt haben möchte ...
der client muss darauf hin mit einem spezifierten PONG *ping-response* antworten ... andernfalls wird die verbindung getrennt* ... muss dieses ersteinmal wieder in seine bestandteile zerlegt werden
dazu bediesen wir uns entweder java.lang.String.split(String regex) oder z.B. dem StringTokenizer
hierbei muss auf korrekte implementation geachtet werden ...
in der ersten phase darf nur an
"|"
getrennt werden ... *einmal bei COMMAND|FILE ; zweimal bei COMMAND|OPTION|FILE*
daher ist es beim zusammenbau des strings auf der anderen seite unbedingt zu vermeiden das genau dieses sonderzeichen *ja es sind zwar 3 zeichen .. aber es wird als ein trenner gehandhabt* nur an den dafür vorgesehen stellen auftaucht ...
sollte es nicht möglich sein dies einzuhalten muss es entsprechend maskiert werden damit genau diese regel erfüllt wird
wenn wir also an unserem trenner getrennt haben haben wir folgende drei teil-strings
"COMMAND
OPTION
FILE"
die beiden anführungszeichen vorne und hinten können jetzt weg *waren halt nur drum zur vermeidung von fehlerhaften trennungen des strings*
dann muss man sich überlegen was sinnvoller ist ...
erst versucht die OPTION zu parsen *VORHER natürlich chekcen ob überhaupt das OPTION-tag vorhanden ist*
oder aber erst zu kuggn welches COMMAND vorliegt um sich darauf vorzubereiten das es eventuell garkein OPTION-tag gibt welches noch zusätzlich geparst werden muss ...
ich würde die letztere variante bevorzugen ... wobei es sicher auch dinge gibt wo die erste durchaus sinn machen wird
für den fall das OPTION noch geparst werden muss
einfach wieder am trenner *diesmal &* trennen ...
dann haben wir erstmal die OPTION=VALUE - paare ...
da kann man entweder drüber-iterieren oder in einer Map *geht hier auch property ? .. mal bitte was sagen wenn ja* die entsprechent gestaltet ist speichern
das wäre eigentlich alles zum punkt OPTION
nach dem wir also unseren fest-spezifizierten string wieder zerlegt haben beginnt das interpretieren der informationen
dazu geb ich jetzt hier kein beispiel ... ich denke dass solltest du auch alleine hinbekommen
analog geht natürlich das senden von informationen
einfach von hier unten anfangen und dann wieder nach oben alles verschachteln ... zum schluss kommt dann oben an der stelle wo ich geschrieben hab "wenn nun einer der beiden ein solches kommando bekommt" wieder das fertige kommando zustande
die ganze kommunikation *netzwerk , internet* und die umsetzung der befehle ist jetzt dein restlicher part der implementation ...
ich habe dir jetzt hier lediglich ein beispiel-protokoll geliefert wie ich das angehen würde ...
wie du es jetzt umsetz und ob es dir reicht .... nun ... das hängt von dir und davon ab was du damit machen willst
hoffe ich konnte dir helfen ... auch wenn es mal wieder extrem lang geworden ist ...