boost::asio example



  • Wieso geht der Programmierer dieses Beispiels: http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/example/chat/chat_client.cpp

    davon aus, dass boost::asio::async_write den ganzen buffer in einem Rutsch sendet bzw. dass boost::asio::async_read mit einem Mal alles einliest?

    Müsste er nicht bytes_transffered kontrollieren?

    siehe Methoden: do_write, handle_write, handle_read_*

    Wäre um jede Klarstellung dankbar, Danke!



  • Das Bsp. ist ok. Siehe Doku zu boost::asio::async_read(..):
    http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/reference/async_read/overload1.html
    Es wird genau soviel gelesen wie beim Aufruf spezifiziert (oder es wird ein Error signalisiert).



  • theta schrieb:

    Das Bsp. ist ok. Siehe Doku zu boost::asio::async_read(..):
    http://www.boost.org/doc/libs/1_46_1/doc/html/boost_asio/reference/async_read/overload1.html
    Es wird genau soviel gelesen wie beim Aufruf spezifiziert (oder es wird ein Error signalisiert).

    Aber hier sagst du was anderes: http://www.c-plusplus.net/forum/p2048987#2048987
    Dort meinst du, dass die Nachricht zerstückelt ankommen kann

    Oder verstehe ich dich einfach falsch?
    Ich verstehe dich nämlich so:
    Wenn mein buffer ein std::array<char, 8192> groß ist und ich eine Nachricht empfange die 4096 bytes groß ist, würde laut meines Verständnisses deiner Aussage der read_handler genau einmal aufgerufen werden.

    Wäre jedoch die empfangene Nachricht 10240 bytes groß, wäre bytes_transferred == 8192 und ich müsste nochmal asio::async_read aufrufen um den Rest der Nachricht einlesen zu können.



  • also die fragen die sich mir stellen sind nun

    welche von den aussagen stimmt?
    muss ich bei einem boost::asio::async_(write/read) überprüfen ob das ausgehende Packet in seiner gesamten Größe gesendet wurde oder nicht?

    der post liest sich angreifend an, ist er aber nicht. er ist sehr nett gemeint. ich bin nur etwas verwirrt, weil ich es richtig machen will aber mehrere aussagen lese.

    wäre dir dankbar wenn du mir eine antwort schreiben könntest.

    danke



  • Ob Du prüfen musst wieviele Bytes gesendet/empfangen wurden hängt davon ab welche Methode Du dazu aufrufst.

    Bsp.

    boost::asio::async_read(..) empfängt GENAU soviel wie im Buffer angegeben
    boost::asio::ip::tcp::socket::async_receive(..) bzw. async_read_some(..) empfangen maximal soviel wie im Buffer angegeben ist, der Handler kann aber auch früher augerufen werden

    Auch brauchst Du ein Protokoll - im Fall des Chats wird mit fixen Message Längen gearbeitet - desshalb kann boost::asio::async_read(..) benutzt werden. Es nimmt dir die "Protokoll Implementaion" ab.

    Edit:

    der post liest sich angreifend an, ist er aber nicht. er ist sehr nett gemeint. ich bin nur etwas verwirrt, weil ich es richtig machen will aber mehrere aussagen lese.

    Nur keine Angst - das haut mich schon nicht aus den Socken.. 🕶



  • Kannst du nur noch zur Klarstellung meinen Post mit 'Genau' und 'Falsch' beantworten?

    Wenn ich boost::asio::async_read mit einem Buffer von 8192 bytes verwende, dann wird der completion_handler erst dann aufgerufen, wenn die 8192 bytes beschrieben wurden (oder ein error tritt auf)? -> das heißt es wäre nicht klug einen zu großen Buffer(8192) zu verwenden, wenn die Messages sich bspw. auf 20-30 Zeichen beschränken, richtig?

    Wenn ich boost::asio::async_receive verwende, dann wird der completion_handler undefiniert bzw. ab und an aufgerufen? oder wenn der Buffer voll ist -> ich sehe hier keinen Sinn der Methode. Gibts hier ein Timeout, der den completion_handler flushed oder wird er wirklich irgendwann aufgerufen?

    Danke theta für deine Hilfe. Bin dir sehr dankbar!



  • thankfulperson schrieb:

    ...Gibts hier ein Timeout, der den completion_handler flushed oder wird er wirklich irgendwann aufgerufen?

    Die Doku von boost ist sehr eigen bzw. war ich wahrscheinlich zu lange mit einfacheren Dokus verwöhnt die die Beziehungen zwischen den einzelnen Methoden auch angegeben haben.

    Die 2. Frage wäre somit beantwortet:
    Der Programmierer muss anscheinend mit available in gewissen Zeitabständen schauen ob was im Buffer liegt.



  • thankfulperson schrieb:

    Kannst du nur noch zur Klarstellung meinen Post mit 'Genau' und 'Falsch' beantworten?

    Ja. 🕶

    thankfulperson schrieb:

    Wenn ich boost::asio::async_read mit einem Buffer von 8192 bytes verwende, dann wird der completion_handler erst dann aufgerufen, wenn die 8192 bytes beschrieben wurden (oder ein error tritt auf)? -> das heißt es wäre nicht klug einen zu großen Buffer(8192) zu verwenden, wenn die Messages sich bspw. auf 20-30 Zeichen beschränken, richtig?

    Ja. Exakt das bedeutet es.

    thankfulperson schrieb:

    Wenn ich boost::asio::async_receive verwende, dann wird der completion_handler undefiniert bzw. ab und an aufgerufen? oder wenn der Buffer voll ist -> ich sehe hier keinen Sinn der Methode. Gibts hier ein Timeout, der den completion_handler flushed oder wird er wirklich irgendwann aufgerufen?

    1. Es gibt keine Funktion boost::asio::async_receive(..) nur eine Methode boost::asio::ip::tcp::socket::async_receive(..).
    2. Der TCP Stack entscheidet wann der Handler aufgerufen wird. Nur das Maximum an Bytes im Buffer ist festgelegt - nicht aber das Minimum.

    thankfulperson schrieb:

    Die 2. Frage wäre somit beantwortet:
    Der Programmierer muss anscheinend mit available in gewissen Zeitabständen schauen ob was im Buffer liegt.

    Nein, muss man nicht - kann man. Normalerweise wird es nicht benötigt!

    Simon



  • Passt. Perfekt. Danke Simon! 🙂 👍



  • theta schrieb:

    1. Es gibt keine Funktion boost::asio::async_receive(..) nur eine Methode boost::asio::ip::tcp::socket::async_receive(..).
    2. Der TCP Stack entscheidet wann der Handler aufgerufen wird. Nur das Maximum an Bytes im Buffer ist festgelegt - nicht aber das Minimum.

    Langsam finde ich mich zurecht in der Dokumentation von boost.
    Vielleicht für den ein oder anderen:

    async_write(2 overloading)
    async_read(2 overloading)

    Den 3. Parameter 'CompletionCondition' könnte man verwenden um ein Minimum anzugeben, wie beispielsweise:
    transfer_at_least(n)


Anmelden zum Antworten