Boost::Asio - boost::asio::ip::tcp::socket::read_some()
-
Hallöle,
ich schreibe Just4Fun einen TCP-Chat mit Boost::Asio. Genauer gesagt den Server. Die boost::asio::write()-Funktion hat wunderbar funktioniert, allerdings schmeisst er mir beim Aufruf von boost::asio::ip::tcp::socket::read_some() eine Exception und springt zu einer Stelle in der xutility. Ich möchte die besagte Stelle nun nicht posten... werde ich aber gerne tun wenn es euch hilft mir zu helfen
. Also, hier die mem fnc:const std::pair<const std::size_t, const boost::array<std::string, 1024>> TCPSyncServer::GetMessageFromClient() { boost::array<std::string, 1024> Message; // 1KB = max length of message boost::system::error_code ignored_error; const std::size_t length = m_pSocket->read_some(boost::asio::buffer(Message), ignored_error); return std::pair<const std::size_t, const boost::array<std::string, 1024>>::pair(length, Message); }(Übrigens; Mit der Übergabe eines std::string an boost::asio::buffer() in boost::asio::ip::tcp::socket::read_some() ist so ziemlich alles explodiert^^, weswegen ich nun die Alternativlösung mit boost::array gewählt habe)
Bevor ihr an Fehler in anderen Codesegmenten denkt: Der Server funktioniert einwandfrei, synchronisiert sich mit dem Clienten und schickt sogar Nachrichten an ihn. Nur diese mem fnc schiebt etwas Stress nach der Synchronisation.Ich weiß nicht genau wann mein Chat-Client-Partner mir etwas geschickt hat, aber ich nehme an, dass er crasht wenn eine Nachricht auf dem Socket liegt, bzw. ich danach anfrage.
Zusatzinformation: Mein Gegenüber hat sich per Telnet mit mir synchronisiert und, wie ich denke, einfach wild in die Konsole getippt und Enter gedrückt. Falls es eine Möglichkeit gibt, mit Befehlen Nachrichten per Telnet zu verschicken, dann nennt mir bitte welche, denn ich habe nichts bei Google gefunden.
Ich danke vielmals im Voraus!
-
boost::array<std::string, 1024> message boost::asio::buffer(message);WTF?

Und das kompiliert? Naja, wie auch immer, lies mal die Dokumentation:
http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/buffer.htmlZum Beispiel den ersten Satz:
The
boost::asio::bufferfunction is used to create a buffer object to represent raw memory, an array of POD elements, a vector of POD elements, or astd::string.Ich kann da nichts lesen von "array of
std::string".Kóyaánasqatsi schrieb:
(Übrigens; Mit der Übergabe eines std::string an boost::asio::buffer() in boost::asio::ip::tcp::socket::read_some() ist so ziemlich alles explodiert^^, weswegen ich nun die Alternativlösung mit boost::array gewählt habe)
Wenn du die Dokumentation gelesen hättest (gleiche Seite), dann wüsstest du, dass man über
std::stringnur einenconst_bufferbekommen kann, was aber beim Empfang nicht zulässig ist, da braucht es einenmutable_buffer.Grüssli
-
Oh ok. Danke schön erstmal! Ich habe die Methode nun noch einmal umgebaut und loope sie nachdem eine Verbindung besteht in einer extra for()-Schleife:
const std::pair<const std::size_t, const std::vector<char>> TCPSyncServer::GetMessageFromClient() { std::vector<char> Message; boost::system::error_code ignored_error; const std::size_t length = m_pSocket->read_some(boost::asio::buffer(Message), ignored_error); if(ignored_error) throw boost::system::system_error(ignored_error); return std::pair<const std::size_t, const std::vector<char>>::pair(length, Message); }Zudem sollte gesagt sein, das ich ziemlich neu in der Thematik bin, also büdde nit so feste uffn Kopp hauen

Zu dem Problem: length ist immer 0! Warum? Was mache ich falsch?
-
Kóyaánasqatsi schrieb:
Zudem sollte gesagt sein, das ich ziemlich neu in der Thematik bin, also büdde nit so feste uffn Kopp hauen

Du solltest doch schon Erfahrung haben mit der Programmierung und das Lesen von Dokumentation & Referenzen sollte ja wirklich das Einfachste sein

Kóyaánasqatsi schrieb:
Zu dem Problem: length ist immer 0! Warum? Was mache ich falsch?
Weil dein Puffer (namentlich
Message) eine Länge von 0 hat. Schau dir mal die Beispiele in der Dokumentation an. Du musst einen Puffer mit einer gewissen Grösser übergeben. Dieser wird dann entsprechend befüllt.Wenn du willst, dass dein Puffer wächst mit dem Empfang und dabei bis zum Beispiel einem Zeilenende gelesen werden soll, dann musst du mit
boost::asio::read_untilund mit einemboost::asio::streambufarbeiten. Näheres dazu findest du in den Codebeispielen von den HTTP Clients und Server und der Referenz zu den Funktionen.Grüssli
-
Dravere ich will ein Kind von dir

Danke!
-
Kóyaánasqatsi schrieb:
Dravere ich will ein Kind von dir

Das kostet aber was! Ich verkaufe gerne die störenden Nachbarskinder, aber diese zu entführen und verschicken kostet halt einiges. Zudem möchte ich ja auch einen Gewinn davon haben, abgesehen dass es dann endlich ruhiger wird ...

Grüssli
-
Bei read_until ist zu beachten, dass danach u.U. mehr Daten im übergebenen Puffer stehen, als zur Erfüllung der "until" Bedingung nötig wären.
(Wurde so gemacht, weil eine Implementierung die nie mehr liest als nötig ist eine Performance-Katastrophe gewesen wäre)Der zurückgegebene size_t gibt natürlich die Länge der kleinsten Sequenz an, die die Bedingung erfüllt.
Wenn man immer mit read_until arbeitet, immer das selbe Puffer Objekt verwendet, und die "konsumierten" Daten vom Anfang des Puffers entfernt, dann funktioniert das auch ganz gut.Da es etwas kontra-intuitiv ist, wollte ich es trotzdem erwähnen.
BTW: ein Thread auf der Boost-Mailing-Liste zu dem Thema: