boost::asio client sendet manchmal Misst und bleibt hängen
-
Hi!
Schreibe gerade an nem Client und nem Server mit boost::asio!
Nachdem sich der Client verbunden hat, sendet er einen "Authentification Key" um sicherzustellen, dass der Client auch wirklich meiner ist und nicht irgend ein anders Programm.
Jetzt hab ich das Problem, dass beim Server es vorkommt, dass beim Senden/Empfangen des Keys einfach nur Müll ankommt. Entweder es kommt nur totaler Schrott an (irgendwelche wirren Zeichen), oder es kommt der Key an sich zwar richtig an, aber angehängt hintendran auch noch lauter seltsame Zeichen. Woran kann das liegen? Hier mal der relevante Sourcecode:
Server:std::string server::GetMessage() { std::string Buffer; boost::asio::async_read(m_socket, boost::asio::buffer(Buffer), boost::bind(&client::message_handleshared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) ); return Buffer; }Client:
int client::SendMessage(std::string Message) { boost::system::error_code error_c; boost::asio::write(socket,boost::asio::buffer(Message),boost::asio::transfer_all(),error_c); if(error_c == boost::asio::error::connection_aborted)//connection closed { std::cout << "Connection closed!" << std::endl; return 2; } return 0; }Dann habe ich noch ein weiteres wirklich seltsames Problem, das ich mir nicht erklären kann. Er tritt anscheinend beim Verbinden zum Server auf
Hier mal der Code:void Connect(std::string IP, std::string Port) { tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);//resolve the hostname/ip tcp::resolver::iterator end; boost::system::error_code error_c = boost::asio::error::host_not_found; std::cout << "Connecting to " << IP << "..."; while (error_c && endpoint_iterator != end)//connect { socket.close(); socket.connect(*endpoint_iterator++, error_c); } if (error_c)//if error::host_not_found { std::cout << "Coulnd't find the Host!" << std::endl; return 1;//error 1 } std::cout << "connected!" << std::endl;//DAS HIER ZEIGT ES AN std::cout << "Authentificating..."; //DAS HIER ZEIGT ES NICHT AN //... }Es geht um die letzten beiden 'std::cout'...das erste "connected!" zeigt es mir noch ganz normal an. "Authentificating..." zeigt es dann einfach nicht mehr an. Allerdings hängt sich das Programm nicht wirklich auf. Bei '//...' geht es weiter mit dem Code zum schicken des AuthentificationKeys und mehr empfangen/senden und es funktioniert alles einwandfrei. Nur zeigt es mir kein einziges std::cout mehr an ab dem Zeitpunkt. Wenn ich zwischen die 2 std::couts oben allerdings einen boost::asio::deadline_timer packe:
std::cout << "connected!" << std::endl;//das zeigt es an deadline_timer.wait(); std::cout << "Authentificating...";//das zeigt es mir jetzt auch an!, dann funktioniert das 2. std::cout...allerdings alle folgenden std::couts auch nicht mehr.
Des weiteren hab ich das hier getestet:std::cout << "connected!" << std::endl;//das zeigt es an std::cerr << "Authentificating...";//funktioniert jetzt auch...
Das funktioniert zwar, aber danach zeigt es mir wiederum kein einziges std::cout oder std::cerr mehr an!
Das ist einer der seltsamsten Fehler die ich in über 2 Jahren programmieren jetzt hatte 
Hoffe mir kann jemand bei den beiden Problemen helfen
Gruß,
Finn
-
Zu deinem 2. Problem.
Du mußt den std::cout flushen
std::cout.flush();oder
std::cout << std::endlflushed ihn ebenfalls (+Zeilenumbruch).
Gruß,
XSpille
-
Wo genau muss ich das denn machen? Habs direkt nach dem std::cout mit "connected!" versucht. Geht immer noch nicht

-
Finn schrieb:
Wo genau muss ich das denn machen? Habs direkt nach dem std::cout mit "connected!" versucht. Geht immer noch nicht

Jedes mal wenn du etwas in std::cout schreibst, kann es potentiell gecached
werden.Ich dachte an:
std::cout << "Authentificating..." << std::endl;bzw.
std::cout << "Authentificating..."; std::cout.flush();
-
Das hier:
std::string server::GetMessage() { std::string Buffer; boost::asio::async_read(m_socket, boost::asio::buffer(Buffer), boost::bind(&client::message_handleshared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) ); return Buffer; }geht so schon mal nicht.
async_readkommt sofort nach dessen Aufruf zurück.Das Empfangen der Daten und der Aufruf des Empfangdshandlers, wird im asio-Framework abgehandelt. Das bedeutet aber auch, dass das zum Puffern benutzte Objekt gültig bleiben muss, bis der übergebene Handler aufgerufen wird. Bei Deiner Funktion ist das nicht der Fall:
Du legst lokal ein String an, rufst damitasync_readauf, das kommt dann sofrt zurück, und dann ist Deine Funktion zu Ende, und das String-Objekt wird zerstört.async_readarbeitet danach auf Speicher, welcher Dir nicht mehr gehört -> Undefined Beahviour.Das nächste Problem ist, dass Du für den Empfang einen Puffer in einer bestimmten Größe vorhalten musst.
asiopasst die Puffergröße nicht automatisch an.Wenn Du Telegramme unterschiedlicher Länge empfangen willst, musst Du die Länge erst in einem Telegramm übertragen, dann damit den Empfangspuffer anpassen, und dann, in einem zweiten Telegramm, die eigentlichen Daten senden.
Ein
std::stringist als Empfangspuffer ungeeignet. Einstd::vector<char>ist besser.
Mich wundert ganz ehrlich, dass das Programm überhaupt etwas empfängt. Ich hätte eher einen Absturz erwartet.
-
Ah danke Tachyoin
Klingt logisch! Werd ich mal überarbeiten 