Boost::Asio - async_read!?



  • Hallo,
    ich habe einen Clienten der ein Datenpaket zum Server schickt. Jedes Datenpaket besteht aus ID + Data. So, ich receive die ID (int) mit async_read. Das klappt auch wunderbar. Nun möchte ich allerdings den Data-Anhang receiven. Hier die Funktion:

    (Nicht erschrecken, ich habe die Funktion jetzt schon öfters aus Testzwecken umgebastelt)

    template <typename PackageType>
    			void ReceivePackageData(const PackageType &Data, const unsigned int &ID)
    			{
    				std::vector<PackageType, std::allocator<PackageType>> DataBuffer(sizeof(PackageType));
    
    				boost::asio::async_read(m_Socket, 
    										boost::asio::buffer(DataBuffer),
    										boost::asio::transfer_all(),
    										boost::bind(&Network::AsyncTCPServer::HandleRead,
    													this,
    													boost::asio::placeholders::error,
    													boost::asio::placeholders::bytes_transferred,
    													ID));
    
    			}
    

    Die Datenpakete sind bei mir einfache Strukturen. Zuerst wollte ich direkt über einen Zeiger auf die Struktur den Inhalt, der auf dem Socket liegt, in die Instanz einlesen (http://think-async.com/Asio/boost_asio_1_3_1/doc/html/boost_asio/reference/buffer/overload6.html). Den const_buffer mochte er allerdings nicht, er wollte also einen mutable_buffer. Also gut dachte ich mir, knallste ihm halt alles in einem Vector da hin. Aber NEIN, Fehlanzeige. Ich habe jetzt testweise einfach mal einen std::vectorstd::string buf(25); versucht zu übergeben, weil das Datenpaket aus genau dem selben Datentypen besteht, aber wieder Fail.

    Egal was ich mir vo dem Socket holen will, jedesmal schmeisst er mir die Exception:
    Unhandled exception at 0x77a6f217 in Test.exe: 0xC0000005: Access violation reading location 0x00239307.

    Manchmal springt er auch zu irgendeiner Destructor-Funktion aus der Datei "xmemory".

    Ich hoffe mir kann einer helfen, weil langsam raffe ich gar nichts mehr... !?!?

    Danke im Voraus!



  • Lies mal die Doku und fummel nicht nur rum. Dein Empfangspuffer existiert zum Empfangszeitpunkt gar nicht mehr. Außerdem steht in der Doku auch, wie Empfangspuffer aussehen müssen. Ein Vektor aus std::string geht auf jeden Fall nicht.
    Von so einem Quark wie sizeof(string) mal ganz abgesehen. Asio ist recht komplex in der Benutzung. Die C++ Grundlagen sollte man auf jeden Fall beherrschen. Grundlagen in Socketprogrammierung sind auch nötig. Beides fehlt Dir noch, wie man sieht.



  • Als ich deinen Namen gelesen habe erst: "YEEEEHAAAA", dann: "hä o0" und dann "AHHH". Aber irgendwie verstehe ich immer noch nicht was da nicht stimmen soll...

    Übergebe ich einen int, wird der problemlos empfangen, jedoch meine Struktur nicht, obwohl ich von boost::enable_shared_from_this<AsyncTCPServer> erbe.



  • Dein Empfangspuffer existiert zum Empfangszeitpunkt gar nicht mehr.

    Das heißt nicht umsonst "asio". Der Aufruf wird sofort terminieren. Dadurch läufst du sofort aus der Funktion "ReceivePackageData" raus - und dein DataBuffer exisitert nicht mehr, sobald die Antwort eintrifft.



  • Ein Empfangspuffer muss eine zusammenhängende Sequenz sein. Also z.B. ein std::vector<char>. Komplexe Objekte die intern selbst dynamischen Speicher anfordern sind keine zusammenhängende Sequenzen! Also z.B. ein std::vectorstd::string. Woher soll der Socket Deiner Meinung nach wissen, wie er die empfangenen Bytes da hinein bringen soll? Raten?
    Alle async_* Funktionen kommen sofort zurück. Der Scope der Funktion wird verlassen und alle automatischen Variablen zerstört. Dein Empfangspuffer ist dan futsch...



  • Hallo,
    erstmal besten Dank für die Antworten! 👍

    Tachyon schrieb:

    Von so einem Quark wie sizeof(string) mal ganz abgesehen. Asio ist recht komplex in der Benutzung. Die C++ Grundlagen sollte man auf jeden Fall beherrschen. Grundlagen in Socketprogrammierung sind auch nötig. Beides fehlt Dir noch, wie man sieht.

    Hm, ich denke nicht das mir Grundlagenwissen in C++ fehlt. Die Funktion war zu aller erst dafür gedacht, Pakete alá Strukturen zu empfangen. Das sizeof() ist hier schon richtig gedacht, da alle Pakete konstante Datentypen besitzen. Von der Socketprogrammierung selber habe ich keine Ahnung, richtig. Ist auch meine erste richtige Implementation auf diesem Gebiet.

    @last post
    Ok, alles nachvollziehbar. Ich habe da was von Serialization gelesen, ist es möglich damit Ähnliches zu realisieren?



  • Kóyaánasqatsi schrieb:

    Ok, alles nachvollziehbar. Ich habe da was von Serialization gelesen, ist es möglich damit Ähnliches zu realisieren?

    Ja


Anmelden zum Antworten