boost::asio Problem



  • Hallo Gemeinde,

    ich versuche mich gerade an boost::asio und habe auch meine erste eigne Anwendung geschrieben, jedoch habe ich da ein paar Probleme.

    Setp1:
    Client sendet ein "Hallo" an den Server, der Server gibt dann, was er empfängt auf der Konsole aus. Das funktioniert auch super. Jetzt wollte ich einen Schritt weiter gehen, so das der Server mir auch antwortet.

    Step2:
    Client sendet ein "Hallo" an den Server, der Server soll dann "Hallo Client!" zurück senden.

    Jedoch habe ich das Problem, Das ganix passiert. Es scheint mir so das die in einer Schleifer festhängen. Wenn ich jedoch den Client beende schreibt der Server "Hallo" auf die Konsole.

    Hier mal mein Code:

    Client:

    #include <boost/asio.hpp>
    #include <boost/array.hpp>
    #include <iostream>
    #include <string>
    
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver(io_service);
    boost::asio::ip::tcp::socket sock(io_service);
    boost::array<char, 4096> buffer;
    //std::size_t sent = 0;
    std::string msg;
    
    void read_handler(const boost::system::error_code& ec, std::size_t bytes_transferred)
    {
    	if (!ec) {
    		boost::asio::async_read(sock, boost::asio::buffer(buffer), read_handler);
    	} else {
    		std::cout << std::string(buffer.data(), bytes_transferred) << std::endl;
    	}
    
    }
    
    void write_handler(const boost::system::error_code &ec, std::size_t bytes_transferred)
    {
    	if (!ec)
    		boost::asio::async_read(sock, boost::asio::buffer(buffer), read_handler);
    }
    
    void connect_handler(const boost::system::error_code &ec)
    {
    	if (!ec) {
    		std::cout << "begin writing" << std::endl;
    		msg = "Hello";
    		boost::asio::async_write(sock, boost::asio::buffer(msg), write_handler);
    	}
    }
    
    void resolve_handler(const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator it)
    {
    	if (!ec) {
    		sock.async_connect(*it, connect_handler);
    	}
    }
    
    int main(int argc, const char* argv[])
    {
    	boost::asio::ip::tcp::resolver::query query(argv[1], "9999");
    	resolver.async_resolve(query, resolve_handler);
    	io_service.run();
            return 0;
    }
    

    Im Prinzip recht simpel:
    Wenn eine Verbindung erfolgreich aufgebaut wird, soll der Client "Hello" an den Server schicken und danach auf eine antwort warten.

    Server

    #include <boost/asio.hpp>
    #include <boost/array.hpp>
    #include <boost/filesystem.hpp>
    #include <string>
    #include <iostream>
    
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 9999);
    boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint);
    boost::asio::ip::tcp::socket sock(io_service);
    boost::array<char, 4096> buffer;
    std::string msg;
    
    void write_handler(const boost::system::error_code &ec, std::size_t bytes_transferred)
    {
    }
    
    void read_handler(const boost::system::error_code& ec, std::size_t bytes_transferred)
    {
    	if (!ec) {
    		std::cout << "begin reading" << std::endl;
    		boost::asio::async_read(sock, boost::asio::buffer(buffer), read_handler);
    	} else {
    		std::cout << std::string(buffer.data(), bytes_transferred) << std::endl;
    		msg = "Hello Client!";
    		boost::asio::async_write(sock, boost::asio::buffer(msg), write_handler);
    	}
    }
    
    void accept_handler(const boost::system::error_code& ec)
    {
    	if (!ec)
    		boost::asio::async_read(sock, boost::asio::buffer(buffer), read_handler);
    }
    
    int main()
    {
    	boost::asio::ip::tcp::resolver::query query(boost::asio::ip::host_name(), "9999");
    	boost::asio::ip::tcp::resolver resolver(io_service);
    	boost::asio::ip::tcp::resolver::iterator it = resolver.resolve(query);
    	boost::asio::ip::tcp::resolver::iterator end;
    	while (it != end)
    	{
    		std::cout << it->endpoint().address() << std::endl;
    		++it;
    	}
    
    	acceptor.listen();
    	acceptor.async_accept(sock, accept_handler);
    	io_service.run();
            return 0;
    }
    

    An sich auch recht simpel, wenn der Server startet, soll er erstmal auf eine Client-Nachricht warten. Wenn diese empfangen wurde, soll er diese auf der Konsole ausgeben und um anschluss eine Rückantwort an den Client geben.

    Ich vermute, das mein Problem irgendwo in den Callback funktionen ist, jedoch weiß ich leider nicht was das problem sein könnte. Die Callbackfunctionen sind bei Client und Server jeweils die read_handler und write_handler.

    Hat da jemand eine Idee?

    so long
    jd

    // EDIT: Verdammt, habe ins falche Forum geposted, könnte das jemand mal bitte zu C/C++ verschieben?

    Danke.



  • Lies doch einfach mal die Doku bitte.

    async_read kommt erst zurück, wenn alle übergebenen Puffer voll gelesen wurden.
    Schreiben tust du einen recht kurzen String ("Hallo" eben), und lesen willst du dann 4096 Byte. Wie soll das gehen?

    Du könntest deinen String mit "\r\n" terminieren, und dann statt async_read einfach async_read_until verwenden.


Log in to reply