# Protokoll gesucht



## freez (14. Apr 2012)

Hallo,

ich suche ein Übertragungsprotokoll (natürlich in Java implementiert), welches auf TCP und / oder UDP / IP basiert. Ich möchte kurze Nachrichten übertragen (bis zu 100Zeichen) aber dafür sehr häufig (1000 Stück pro Sekunde / Client). Es gibt Anwendungsfälle wo es wichtig ist, dass alle Nachrichten ankommen aber auch Anwendungsfälle, wo diese Nachrichten verloren gehen dürfen, aber nicht müssen .

Für den Anfang gibt es nur wenig Clients, aber die können auch mehr werden. Übertragen werden die meisten Daten vom Client an den Server und nur wenige zum Client. Verschlüsselung soll das Protokoll automatisch ermöglichen.

Ich habe mir bereits HTTP / HTTPs angeschaut. Aber dadurch, dass ich der Verbindungsaufbau "so lange" dauert, komme ich etwas in Bedrängnis bei 1000 Aufrufen / Sekunde / Client, da eine Abarbeitung auf meinem Testserver (Tomcat 7 Servlet, mit Datenhaltung nur im RAM, keine DB) ca. 50ms. dauert (grad bei https). Vielleicht liegt es aber auch an meinem Setup.  Ich habe auch schon versucht diese Nachrichten zu bündeln und gleich 20 Stück per HTTPs GET übertragen. Aber das brachte nur minimale Verbesserung. Ich fand aber an diesem Protokoll gut, dass ich auch parallele Anfragen schicken konnte um vielleicht andere NachrichtenTypen zur gleichen Zeit zu senden. Vielleicht hat jemand von euch auch andere Erfahrung mit dem Protokoll gemacht. Ich sehe das größte Problem darin, dass die Verbindung scheinbar immer wieder neu aufgebaut wird. Kann mich aber auch täuschen.

Noch mal zusammengefasst: Verschlüsselte Datenübertragung (nicht grad die einfachste Verschlüsselung, aber Performance ist hier wichtiger als der beste Schutz), schneller Verbindungsaufbau, bidirektionale Verbindung, 100 Zeichen / Nachricht (ca. 780Kbit/s Nettodaten bei 1000 Nachrichten pro Sekunde), wenig Overhead.

Das Protokoll soll deshalb so "schnell" und "klein" sein, weil es auch über WLAN sicher funktionieren sollte.

Hat jemand Vorschläge dazu? Ich wollte mal in die Runde fragen, bevor ich selbst anfange was zu kreiren.


----------



## TheDarkRose (14. Apr 2012)

Ich würde hier auch ein Protokoll verzichten und einen einfachen per SSL verschlüsselten TCP Tunnel aufbauen und über diesen die Daten raw versenden, also nur serialisiert. d.h. plain socket programmierung


----------



## freez (14. Apr 2012)

Danke für dein post. das ist genau das, was ich mache, wenn es nix gibt.

Ich suche eine Bibliothek bzw. ein Protokoll die mir das alles abnimmt, sodass ich nur noch connect und send machen muss. Fürs empfangen vielleicht ein listener registrieren. Verschlüsselung geht dann fast von allein.

Auf Server Seite will ich nur die Nachricht empfangen und ggfs. antworten.

Bestes Beispiel sind servlets . doget wird beim empfangen ausgeführt und sendet eine Antwort. um Verschlüsselung muss ich mich nicht kümmern. So ähnlich möchte ich es auch haben, nur das ich auch Nachrichten ohne anfrage schicken können. und es soll schnell sein .


----------



## Marcinek (14. Apr 2012)

Wenn du Servlets als Alternative hier nennst, dann kann man doch auch diese in Betracht ziehen:

Corba, EJB, RMI, NIO, Servlets, Webservices


----------



## irgendjemand (15. Apr 2012)

1000 queries in 1 sekunde ... das wären 1ms pro query ... und dann noch mit 100bytes nutzdaten ... da kommt was zu sammen ...

alleine an nutzdaten wären das 100B*1000=100000byte/s = 97,66kB/s
bauen wir darum mal noch einen etwas überdimensionierten overhead kommen wir auf rund 1MBit/s ... was von heute üblichen (W)LAN installationen locker bewältigt werden kann ...

dann sollte man sich auch über UDP und TCP genau informieren ...

UDP ist halt verbindungslos ... man schreibt also einfach pakete auf die leitung und hofft das diese überhaupt ankommen ...
TCP ist verbindungsorientiert ... und erzeugt damit alleine schon wegen dem handshake einen gewissen overhead und eine gewisse grundlatenz beim verbindungsaufbau ... auch wird garantiert das pakete in der richtigen reihenfolge ankommen ... geht was verloren wird es erneut angefordert -> noch mehr overhead durch bestätigungen ...

um nun sinnvoll 1MBit/s zu erreichen sollte man bei TCP einfach die verbindung aufbauen und dann die daten raw rüber schicken ... für crypto würde ich ne factory ala SSL/TLS nutzen anstatt selbst was zu basteln

standards wie HTTP sind hier völlig ungeeignet da diese die verbindung aufbauen ... daten senden ... auf antwort warten ... und dann wieder abbauen ... damit schafft man keine 1000 queries / sekunde / client ... schon gar nicht wenn der server für die verarbeitung EINER anfrage 50ms braucht ...

UDP würde sich schon eher anbieten ... alerdings nur dort wo daten auch verloren gegehen können oder die reihenfolge wie sie beim empfänger eintreffen nicht wichtig ist ...
verschlüsselung muss man hier allerdings selbst auf "nutzdaten-ebene" implementieren ... was wiederum den rechenaufwand und overhead erhöt ...

ich denke allgemein ist deine anforderung mit 1k queries / sec / client mit je 100byte nutz-daten ziemlich krass ... da du alleine bei 100 clienten mit einer datenflut von 100MBit/s konfrontiert wirst ...


----------



## freez (15. Apr 2012)

irgendjemand hat gesagt.:


> standards wie HTTP sind hier völlig ungeeignet da diese die verbindung aufbauen ... daten senden ... auf antwort warten ... und dann wieder abbauen ... damit schafft man keine 1000 queries / sekunde / client ... schon gar nicht wenn der server für die verarbeitung EINER anfrage 50ms braucht



Das habe ich auch schon festellen können.




irgendjemand hat gesagt.:


> ich denke allgemein ist deine anforderung mit 1k queries / sec / client mit je 100byte nutz-daten ziemlich krass ... da du alleine bei 100 clienten mit einer datenflut von 100MBit/s konfrontiert wirst ...



Nein, momentan werden es nur eine handvoll Androidgeräte sein, die Messdaten schicken. Ich brauche nur in der Entwicklungsphase so viele Daten pro Sekunde. Später würde ich dieses Art der Datenübertragung einfach nutzen um wenige Informationen pro Sekunde zu übertragen. Wenn ich es nun selbst entwicklen muss, wäre es für die Zukunft nicht ganz umsonst, auch wenn ich in der Zukunft HTTPs verwenden könnte. Aber ich brauche nun mal jetzt für Fehlersuche so viele Daten pro Sekunde.



irgendjemand hat gesagt.:


> um nun sinnvoll 1MBit/s zu erreichen sollte man bei TCP einfach die verbindung aufbauen und dann die daten raw rüber schicken ... für crypto würde ich ne factory ala SSL/TLS nutzen anstatt selbst was zu basteln



d.h., du kennst kein Projekt / Protokoll, welches sowas schon kann und einfach zu nutzen wäre und empfiehlst mir eine Eigenentwicklung?


----------



## freez (15. Apr 2012)

Marcinek hat gesagt.:


> Wenn du Servlets als Alternative hier nennst, dann kann man doch auch diese in Betracht ziehen:
> 
> Corba, EJB, RMI, NIO, Servlets, Webservices



RMI kenne ich am Rande und würde spontan dazu sagen, dass es nicht das ist, was ich brauche.
Servlets habe ich bereits ausgeschlossen, da HTTPs

NIO würde ich wohl nehmen wenn ich nix finde, da dies wohl einer Eigenentwicklung gleicht
Webservices müsste ich mir anschauen, ob die mir genug Arbeit abnehmen
EJB kenne ich auch am Rande und kann mir grad nicht vorstellen, wie das mir helfen soll
Corba kenne ich nicht, muss ich mir anschauen

Danke für die Tipps.


----------



## freez (15. Apr 2012)

irgendjemand hat gesagt.:


> dann sollte man sich auch über UDP und TCP genau informieren



Mir sind die Netzwerkgrundlagen durchaus bekannt und habe auch schon kleinere Sachen mit TCPServerSockets gemacht.


----------



## irgendjemand (15. Apr 2012)

@MOD *vote for merge

@TO
und warum schreibst du jetzt in 10min gleich 3 posts ... und zwei davon auch noch an den selben user *mich* gerichtet ?
das ist hier ungern gesehen und laut forenregeln auch nicht gestattet ...


ansonsten : was ich meinte ist das es sinnvoller ist einemal eine verbindung aufzubauen ... und diese dann offen zu halten und dann die daten über diesen stream zu schicken ... da fast alle protokolle für diese aufgabe immer wieder neue verbindungen nutzen würden *gerade HTTP*

es ist also durch aus einfacher und vor allem perfomanter selbst was zu basteln ...

und warum du zur fehlersuche so viele daten brauchst ... obwohl dann später im einsatz weniger drüber läuft ... hmm .. alles sehr wage ... ich denke hier legen grundlegende konzeptionsfehler vor


----------



## Marcinek (15. Apr 2012)

irgendjemand hat gesagt.:


> fast alle protokolle für diese aufgabe immer wieder neue verbindungen nutzen würden *gerade HTTP*



HTTP 1.1 auch?


----------



## irgendjemand (15. Apr 2012)

bei HTTP 1.1 müssen alle zwischen-instanzen *also alles wo der stream durch geht* dies auch vollständig unterstützen ...

an sich hast du recht : HTTP 1.1 keep-alive wurde genau dafür entwickelt das man eben über EINE tcp verbindung möglichst viele anfragen senden kann ...

in wie weit jedoch der client *also die verwendete java lib* und der server das unterstützen und umsetzen können ist die entscheidene frage ...

die meisten webserver verwenden zwar HTTP 1.1 ... weigern sich aber das keep-alive richtig um zu setzen *zumindest apache 2.2.x schafft es irgendwie nicht* habe ich es mal also grobe bedingung angemerkt ... *da ich eben auch nicht sicher bin ob Java7 *wenn dann bitte* damit auch richtig umgehen kann ... zumindest URL.openConnection() dürfte hier ausscheiden ...*


----------



## freez (15. Apr 2012)

irgendjemand hat gesagt.:


> @TO
> und warum schreibst du jetzt in 10min gleich 3 posts ... und zwei davon auch noch an den selben user *mich* gerichtet ?
> das ist hier ungern gesehen und laut forenregeln auch nicht gestattet ...



Dies war mir bis jetzt nicht bewusst. Mir ist im nachhinein nur noch was aufgefallen (2x halt) und wenn ich neuen Content habe, ändere ich ungern meinen Post, weil die neuen Infos untergehen können, falls schon jemand liest. Da der neue Content eher eine Ergänzung ist, hielt ich es für ratsamer dies so zu handhaben.

@Mod: sehe ich das falsch, oder soll ich lieber meinen Post ändern, wenn mir noch etwas einfällt?



irgendjemand hat gesagt.:


> und warum du zur fehlersuche so viele daten brauchst ... obwohl dann später im einsatz weniger drüber läuft ... hmm .. alles sehr wage ... ich denke hier legen grundlegende konzeptionsfehler vor



Da hast du mich falsch verstanden. Ich brauche später für andere Kommunikationen auch eine Lösung. Meine 1000Daten / Sekunden werde ich später nicht reduzieren, sondern nicht mehr benötigen, da die Entwicklung des Systems dann abgeschlossen ist. In den produktiven Betrieb wird diese Funktion nie übergehen. Aber ich kann diese Kommunikationsschnittstelle ja gleich für andere Sachen auch nutzen.



Nichts desto trotz suche ich immer noch eine Bibliothek / Protokoll, die mir das ganze Handling der Daten abnimmt, sodass ich eigentlich nur noch meine Nachrichten im Client puschen muss und auf Serverseite "plumpst" sie einfach in eine Methode rein. Ich habe nach den Tipps von Marcinek recherchiert und bin dabei auf das Apache Mina Projekt gestossen. Ich arbeite mich gerade durch, und es sieht nicht schlecht aus.


----------



## Marcinek (15. Apr 2012)

Sind dafür nicht genau Message Driven Beans entwickelt worden? ;D


----------



## freez (15. Apr 2012)

Marcinek hat gesagt.:


> Sind dafür nicht genau Message Driven Beans entwickelt worden? ;D



Jetzt bin ich grad nicht so tief drin, aber braucht man dafür nicht auf beiden Seiten J2EE? Ich habe auf Clientseite Android (ab 2.2) und auf Serverseite bin ich frei und möchte eh später Tomcat bzw. wenns nötig sein sollte Glassfish einsetzen.


----------



## TheDarkRose (15. Apr 2012)

Wie gesagt, so kompliziert ist ein SSL Socket auch nicht.


----------



## Lumaraf (15. Apr 2012)

Wenn du häufig darauf angwiesen bist Antworten auf früher Request für einen neuen Request zu bekommen solltest du TCP_NODELAY auf Client und Serverseite aktivieren. Ansonsten solltest du bei HTTP darauf achten Keep-Alive und wenn möglich auch Pipelining zu verwenden. Alternativ könntest du dir auch mal Websockets anschauen.


----------



## JohannisderKaeufer (16. Apr 2012)

Marcinek hat gesagt.:


> Sind dafür nicht genau Message Driven Beans entwickelt worden? ;D



Schließt sich das nicht mit der Forderung



> bidirektionale Verbindung



aus?


----------



## freez (16. Apr 2012)

TheDarkRose hat gesagt.:


> Wie gesagt, so kompliziert ist ein SSL Socket auch nicht.



Das glaube ich voll und ganz. Aber mir geht es auch um mehr. Ich müsste das ganze Handling der Nachrichten übernehmen (voneinander Trennen, Puffern bei Verbindungsabbrüchen), dann um die Threads kümmern, .... usw was alles daran hängt. Es wäre nun mal schön, dass ich es nicht selbst umsetzen muss und suche (in der Hoffnung das mein Problem auch schon viele andere hatten und es gelöst haben) eine Lösung mit der ich nur die Verbindung aufbauen muss und Nachricht schicken kann. Auf Server Seite nur noch einen Handler schreiben, der mir die empfangene Nachricht verarbeitet und ggfs. ne Antwort schickt. Hier fehlt mir auch einfach nur Suchbegriffe, damit ich im Internet recherchieren kann.

Ich möchte es mal an einem anderen Beispiel vergleichen ... ich könnte natürlich mir einen SMTP Client schreiben, welcher direkt auf TCP Sockets aufbaut und das komplette SMTP Protokoll selbst implementieren. Aber es gibt ja die Mail API mit der ich dies einfach lösen kann. Warum sollte ich mir also die Arbeit machen, wenn es bereits einen Standard gibt?
Vielleicht hat jemand anders auch schon das Problem gehabt Nachrichten zwischen Clients und Servern auszutauschen und hat da bereits was auf SSL Socket aufbauend entwickelt und zur Verfügung gestellt.

Aber gut, Apache Mina ist noch im Test. Interessanterweise kann man auch Objekte verschicken, was es für mich noch einfacher macht, da ich die Daten in Java Klassen zur Verfügung habe und auf Serverseite sie auch wieder so benötige.



Lumaraf hat gesagt.:


> Wenn du häufig darauf angwiesen bist Antworten auf früher Request für einen neuen Request zu bekommen solltest du TCP_NODELAY auf Client und Serverseite aktivieren. Ansonsten solltest du bei HTTP darauf achten Keep-Alive und wenn möglich auch Pipelining zu verwenden. Alternativ könntest du dir auch mal Websockets anschauen.



Ich habe mal recherchiert, aber leider keine Infos gefunden wie hoch dabei der Performancegewinn ist. Hast du Zahlen (wegen mir auch geschätzte ) dazu? Sonst müsste ich das mal ausprobieren.


----------



## irgendjemand (16. Apr 2012)

ich denke das hauptproblem wird wie ich bereits sagte einfach die geschwindigkeit sein ...
im rechenbeispiel hab ichs ja schon halbwegs demonstriert : bei 1000 msg / sec wäre das wirklich 1ms je datensatz ... da ist TCP schon nur noch sinnvoll wenn du die verbindung aufbaust ... und dann über diese stehende verbindung die daten überträgst ... ständig verbindung auf bauen ... daten übertragen und wieder abbauen *wie halt z.b. HTTP* scheiden hier auf grund der zeitspanne die alleine der verbindungsaufbau benötigt aus ...
auch hattest du ja was von gesagt das die verarbeitung gut mal 50ms dauern kann ... womit das ganze nicht mehr tragbar ist ...

und UDP ... hmm ... mit ein paar duzend clients kann es in schlechten netzen schon mal zum drop kommen wenn die router und switches meinen das die datenflut zu groß wird ...

was ich allerdings irgendwie immer noch nicht verstanden habe ist warum du ein system entwickeln willst *bzw ein vorhandenes framework nutzen willst* das dir solche hohe datenraten ermöglicht obwohl dies im einsatz nachher überhaupt nicht relevant ist ...

es wird sicher etwas geben was deinen anforderungen gerecht wird ... aber dafür musst du dich erstmal von den "großen" standards lösen bei denen jede nachricht einzeln über ihre eigene verbindung übertragen wird ...
auch wäre mal die frage : wie wichtig ist es das die daten auch wirklich ankommen ? falls wirklich 100% ankommen müssen ... und dann noch in der richtigenreihenfolge ... wäre UDP schon mal garnicht mehr so der beste kandidat ...

auch kommt es auf die leistung der verarbeitung an ... es nützt dir ja nichts wenn du den server mit was weis ich ... mehreren MB die sekunde zukrachst ... dieser aber gerade mal ein paar 100 kB die sekunde SINNVOLL verarbeiten kann und den rest einfach dropped oder es zeitlich einfach nicht schafft ...


auch fand ich die grundfrage nach einem "PROTOKOLL" ziemlich wirr ... da du irgendwie die äußeren rand-bedingungen der meistenprotokolle nicht beachtet hast ... als wäre eher die frage dierekt nach einem "FRAMEWORK" besser gewesen ... den ein protokoll definiert in aller erste linie erstmal nur WIE die daten die übertragen werden darzustellen sind ...
ob dann noch spezifiziert ist wie die verbindung geregelt wird *z.b. unterschied HTTP 1.0 / 1.1* KANN sein ... ist es aber meistens nicht ...


----------



## freez (16. Apr 2012)

irgendjemand hat gesagt.:


> was ich allerdings irgendwie immer noch nicht verstanden habe ist warum du ein system entwickeln willst *bzw ein vorhandenes framework nutzen willst* das dir solche hohe datenraten ermöglicht obwohl dies im einsatz nachher überhaupt nicht relevant ist



Um mal genauer zu werden: Ich muss mehrere PID Regler debuggen (selbst entwickelte), und das geht nun mal nicht mit dem normalen Eclipse Debugger. Nun muss ich pro PID Regler 1000 x mehrere double Werte übertragen und mir die Daten auf einem PC visualisieren. Hier ist es wichtig, dass die Daten ankommen und sich nicht im Client stauen (Android Gerät), aber weniger wichtig, mit welcher Verzögerung ich die Daten auf dem Server bekomme / sehe.

Wie gesagt, ich will später andere Daten übertragen, wobei mir das HTTP Protokoll ausreichen würde. Allerdings würde ich dann einfach auf meine Erfahrungen und Entwicklungen zu dem aktuellen Problem zurückgreifen. Die Anforderungen bzgl. der Datenmenge ist dann nicht mehr so hoch (voraussichtlich).





irgendjemand hat gesagt.:


> auch fand ich die grundfrage nach einem "PROTOKOLL" ziemlich wirr ... da du irgendwie die äußeren rand-bedingungen der meistenprotokolle nicht beachtet hast ... als wäre eher die frage dierekt nach einem "FRAMEWORK" besser gewesen ...



Gebe ich dir recht. Heute würde ich auch behaupten, ich suche ein Framework. Dies ergab sich aber erst aus den Beiträgen hier. Kann man aber nicht die Art, wie ein Framework meine Nachrichten verwaltet und versendet nicht auch als Protokoll verstehen? Dieses Framework muss ja dafür sorgen, dass meine Nachrichten sauber aufgetrennt und wieder zusammengesetzt wird (je nach Größe und Netzwerkverbindung). Ausserdem müssen die Nachrichten an sich voneinander getrennt werden. Dafür müssen Marker oder Informationen zusätzlich hinzugefügt werden. Die Marker dürfen in der Nachricht so nicht ohne weiteres vorkommen ..... usw. Das ist z.B. ein Thema um was ich mich ungern kümmern möchte.


----------



## TheDarkRose (16. Apr 2012)

Später kannst ja auf HTTP umsteigen, aber bei der Menge der Daten bleibt nichts anderes übrig als ein reiner TCP Socket.


----------



## freez (16. Apr 2012)

Apache Mina funktioniert erst mal hervorragend. Sobald man den Verbindungsaufbau hinbekommen hat und die Konfiguration passt, ist es leicht über Handler Objekte zwischen Rechner hin und her zu schieben und mein Code beschränkt sich lediglich auf das eigentliche Handling der Objekte. Wie sie übertragen werden muss mich nicht kümmern. Verschlüsselung muss auch nur konfiguriert werden und den keystore zur Verfügung stellen. Nur fehlt mir abschliessend noch ein Geschwindigkeitstest. Ansonsten bin ich erst mal glücklich.

Danke an alle, die mir geholfen haben.


----------

