frage zu boost asio und netzwerkprogrammierung



  • tzui schrieb:

    1.was würde passieren, wenn nun an stelle 1 bzw 2 10 sekunden pause wären?
    2.wann würde die funktion aufgerufen werden, bzw würde sie überhaupt aufgerufen werden?

    Du meinst 10 Sekunden Pause durch async_wait? Gibt’s nicht, der deadline timer würde nach exakt 5 Sekunden aufgerufen und dann wird weiter async_wait’ed. Sollte allerdings was anderes den Prozess länger als die 5 Sekunden aufhalten (z.B. rechenintensive Operationen) dann würde der deadline_timer so schnell wie möglich aufgerufen werden, im Zweifel sofort. Also Verspätungen sind möglich und treten in der Praxis auch auf.

    Quelle: Viel Erfahrung mit asio und deadline_timer als Basis für nen Echtzeit-Scheduler

    3), 4) und 5) kann jemand anders beantworten :p

    mfg, René~



  • [quote="Nick Unbekannt"]

    tzui schrieb:

    tzui schrieb:

    nun unabhängig von asio:
    4.kann ich dafür sorgen, dass ich von einem socket(egal ob udp oder tcp) genau ein paket gelesen wird, oder kann ich das nur über standatisierte paketlängen machen?

    Du liest genau so viel Bytes, wie du erwartest. Sinnvollerweise kannst du zwischendurch die Daten schon mal weiter verarbeiten.

    falls ich nun schnell hintereinander zwei pakete bekomme und erst dann aus dem stream lese, kann ich dann nur das erste paket einlesen?
    auch wenn ich z.b. einen udp-socket nutze und pakete mit unterschiedlicher länge ankommen? denn dann weiß ich nicht wie lang das erste packet auf dem socket ist, also weiß ich nicht wie viele bytes ich lesen muss.

    NewSoftzzz schrieb:

    Du meinst 10 Sekunden Pause durch async_wait?

    ich meinte durch soetwas wie Sleep, also irgendeine art von delay.
    -----
    also werden die funktionen immer erst bei einem run aufgerufen?
    btw löst hier ein timer nur einmal aus oder habe ich es falsch verstanden und er löst , wie in delphi, mehrmals aus?



  • tzui schrieb:

    falls ich nun schnell hintereinander zwei pakete bekomme und erst dann aus dem stream lese, kann ich dann nur das erste paket einlesen?

    Du bist in der völlig falschen Schicht. Die Pakete brauchen dich gar nicht zu interessieren, diese dienen nur als Rahmen für die eigentliche Übertragung. Dich interessieren nur deine Daten.

    tzui schrieb:

    ich meinte durch soetwas wie Sleep, also irgendeine art von delay.

    async_wait ist wie der Name schon sagt ein asynchrones Warten, d.h. nicht blockierend.

    tzui schrieb:

    also werden die funktionen immer erst bei einem run aufgerufen?

    Ja, die Funktionen werden über einen Ereignishandler aufgerufen und dieser muss natürlich auch vorher gestartet werden. Das ist auch der Grund, warum du aus der Methode nicht zurück kommst. Im Hintergrund läuft dort eine Endlosschleife, die du mit stop() oder ähnliches beenden müsstest. Dann werden aber auch deine Timer nicht mehr zwangsläufig bedient (kommt auf die konkrete Umsetzung in Boost an).

    tzui schrieb:

    btw löst hier ein timer nur einmal aus oder habe ich es falsch verstanden und er löst , wie in delphi, mehrmals aus?

    Sollte eigentlich in der Doku stehen. Aus dem Bauch heraus sehe ich aber keinen Sinn eine Deadline periodisch zu setzen, da sie von einem Startpunkt abhängt. Es gibt aber auch andere Timer die periodisch sind.



  • tzui schrieb:

    1.was würde passieren, wenn nun an stelle 1 bzw 2 10 sekunden pause wären?

    Die Funktion würde sofort aufgerufen werden. Es gilt bei den relativen Zeiten immer der Zeitpunkt, zu dem sie spezifiziert werden. Also im Falle von timer(io_service, boost::posix_time::seconds(5)) Zeitpunkt der Timerobjektkonstruktion + 5 Sekunden.

    tzui schrieb:

    2.wann würde die funktion aufgerufen werden, bzw würde sie überhaupt aufgerufen werden?

    Siehe 1. Mit den von Dir gegebenen Zeiten also sofort in dom Moment, wo Du io_service::run() aufrufst, da die bei der Konstruktion von deadline_timer angegebenen 5 sekunden schon verstrichen sind.

    tzui schrieb:

    async_read_some
    

    3.lese ich damit einzelne pakete (wenn mein buffer groß genug ist)?

    Was heißt "einzelne Pakete"? Eine TCP-Verbindung repräsentiert einen Stream ohne Ende. Wenn Du sowas wie Pakete (oder besser Datagramme) haben willst, nimm UDP.

    tzui schrieb:

    4.kann ich dafür sorgen, dass ich von einem socket(egal ob udp oder tcp) genau ein paket gelesen wird, oder kann ich das nur über standatisierte paketlängen machen?

    Wieder: Was meinst Du mit "genau ein Paket"? Ein IP-Paket?

    tzui schrieb:

    5.ist es bei udp/tcp eher sinvoller viele kleine oder wenige große pakete zu schicken? (was ist performanter?)

    Zum Einen gibt es kein udp/tcp. Es gibt TCP/IP und UDP. Und on groß oder klein besser ist, kann man nicht pauschal sagen. Das hängt u.a. von der Qualität des Netzes ab. Und auch von der Art der Daten, welche man verschickt.

    Wenn Du einen periodischen Timer haben willst, musst Du deadline_timer::expires_from_now() und deadline_timer::async_wait() in Kombination benutzen und Dir das selbst bauen. Von alleine kann der deadline_timer das nicht. Dazu gibt es auch Beispiele in der Doku.



  • Hier noch ein fertiger "repeating timer", basierend auf boost.asio:
    http://www.codegorilla.co.uk/wiki/Asio_Repeating_Timer



  • 1.also wird tcp und udp als endlosstream zur verfügung gestellt?

    2.ich muss also einen thread durch den aufruf von run blockieren, um dann assyncrone funktionen aufzurufen (bzw, damit die funktionen die ich übergeben habe aufgerufen werden)?
    wäre es dann nicht sinnvoller die funktionen gleich in dem thread aufzurufen?



  • tzui schrieb:

    1.also wird tcp und udp als endlosstream zur verfügung gestellt?

    Nein, es liegen genau soviele Bytes vor, wie du geschrieben hast.

    tzui schrieb:

    2.ich muss also einen thread durch den aufruf von run blockieren, um dann assyncrone funktionen aufzurufen (bzw, damit die funktionen die ich übergeben habe aufgerufen werden)?
    wäre es dann nicht sinnvoller die funktionen gleich in dem thread aufzurufen?

    Du verstehst das falsch. Du meldest alle Aktionen bei dem Service-Handler an, die du machen willst und übergibst ihm mit run() die Kontrolle über den Thread. Prinzipiell kannst du natürlich mit einem anderen Thread weiter arbeiten.



  • Nick Unbekannt schrieb:

    Nein, es liegen genau soviele Bytes vor, wie du geschrieben hast.

    ich meinte damit, dass ich nicht unter einzelnen paketen unterscheiden kann, also nicht weiß, wie viele bytes jetzt zusammengehören.

    -----

    mein ziel:
    ich möchte an einen pc daten schicken.
    es ist ok, wenn daten veloren gehen.
    ich muss aber wissen, wie viele bytes zu einem datensatz gehören, damit ich diese bytes zusammen bearbeiten kann.
    hier kann ich entweder einen datensatz pro paket schicken, dann müsste ich aber bytes zu einem packet zuordnen können (um datensätze unterscheiden zu können), oder ich muss immer die länge mitschicken und dann so viele bytes lesen(wäre sicher nicht so performant), oder alle datensätze müssten immer eine bestimmte länge haben(dann würde ich aber unnötig viel schicken, da ich den rest des datensatzes mit nullen auffüllen müsste).
    es darf nicht vorkommen, dass ein datensatz nur teilweise ankommt.
    da afaik udp autoflush hat ist mir leider nicht gewährleistet, dass immer nur ganze datensätze geschickt werden, denn wenn ich zwei packete je 50byte in den stream schreibe und udp dann ein packet mit 50byte losschickt habe ich geteilte packete und der hintetere teil kommt eventuell garnicht an.
    würdet ihr mir empfehlen meinen datenverkehr auf dem iplayer aufzubauen?
    wenn nicht, was würdet ihr mir dann empfehlen?
    ist es beim iplayer gewährleistet, dass packete immer ganz ankommen?

    -----

    Nick Unbekannt schrieb:

    Du verstehst das falsch. Du meldest alle Aktionen bei dem Service-Handler an, die du machen willst und übergibst ihm mit run() die Kontrolle über den Thread. Prinzipiell kannst du natürlich mit einem anderen Thread weiter arbeiten.

    und damit nach den fünf sekunden warten was gemacht werden kann muss ich meinen aktuellen thread blockieren.....
    also kann ich eigendlich garnicht von dem nicht blockierenden warten profetieren, da ich ja dann doch wieder blockieren muss.
    was ist dann eigendlich der sinn von dem ganzen? (ok ich könnte höchstens einen funktionsaufruf machen der sicher kürzer als 5sekunden dauert....)



  • Der Sinn von asynchronen Ereignissen ist, dass du nicht auf sie warten musst. Ein normales synchrones Programm würde blockieren bis das Ergebnis vorhanden ist. Bei einem asynchronen sagst du, hier mach mal und melde dich wenn du fertig bist. Das hat den Vorteil, dass du in der Zwischenzeit etwas anderes tun kannst. Du kannst natürlich auch auf ein asynchrones Ereignis warten, was aber eigentlich keinen Sinn macht.
    Und noch mal zu den Daten, die du über das Netzwerk senden willst. Die Länge der Daten ist von deinem Programm vorgegeben, du brauchst dich dabei nicht zu kümmern, dass sie in ein Frame passen. Das macht für dich alles das System. Du bekommst auch zum Lesen dann nur wieder die Daten, die du gesendet hast. Der Rest wird alles vorher weggenommen und die Pakete wieder in der richtigen Reihenfolge zusammen gesetzt. Um das ein wenig visuell zu untermalen http://upload.wikimedia.org/wikipedia/de/1/14/OSI7Layer_model_3.1.svg .



  • Nick Unbekannt schrieb:

    Du bekommst auch zum Lesen dann nur wieder die Daten, die du gesendet hast.

    ja bei tcp.
    allerdings ist es mir wichtig, dass die daten schnell übertragen werden.
    daten können verloren gehen, das ist egal.
    die frage ist nur:
    ist bei udp garantiert, dass die daten, die ich sendto übergebe entweder komplett in einem packet gesendet werden oder garnicht gesendet werden?
    denn so wäre garantiert, dass entweder mein ganzes datenpack ankommt oder garnichts.


Anmelden zum Antworten