Boost logo

Boost :

From: berserker_r (berserker_r_at_[hidden])
Date: 2006-11-29 10:21:09


I'm still trying to implement a multithreaded http server with asio: the
problem I have reported in the past about IOCP looks fixed but now I'm
falling in another one...If you try the following example it will works
well with IE6 and Opera 9 but not with Firefox 2.0 (it always detect an
aborted connection). To make it works with Firefox just uncomment the
"Sleep(0)". Obiously I don't think that the problem is related to Firefox,
but I cannot understand why it works well with others browsers...

class Session
{
public:
        Session(boost::asio::io_service &service) : m_socket(service) { }
        ~Session() { m_socket.close(); }

        boost::asio::ip::tcp::socket & socket() { return m_socket; }

        void run()
        {
                //Sleep(0); // Uncomment this line to make it works in Firefox

                m_socket.async_read_some(boost::asio::buffer(m_buffer),
                boost::bind(&Session::read_handler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
        }

        void read_handler(const boost::system::error_code &e, size_t
bytes_transferred)
        {
                if(!e)
                {
                        static int counter = 0;
                        std::stringstream stream;
                        stream << "<html><body><h2>Hello" << ++counter << "</h2></body></html>";
                        m_response = stream.str();
                        boost::asio::async_write(m_socket, boost::asio::buffer(m_response),
                        boost::bind(&Session::write_handler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
                }
        }

        void write_handler(const boost::system::error_code &e, size_t
bytes_transferred)
        {
                delete this;
        }

private:
        boost::asio::ip::tcp::socket m_socket;
        boost::array<char, 8192> m_buffer;
        std::string m_response;
};

class Server
{
public:
        Server(int port) : m_service(), m_acceptor(m_service)
        {
                boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(),
port);
                m_acceptor.open(endpoint.protocol());
                m_acceptor.bind(endpoint);
                m_acceptor.listen();
                accept();
        }

        void accept()
        {
                Session *connection = new Session(m_service);
                m_acceptor.async_accept(connection->socket(),
                boost::bind(&Server::accept_handler, this,
boost::asio::placeholders::error, connection));
        }

        void run(int threads = 10)
        {
                boost::thread_group threads_pool;
                while(threads-- > 0)
                        threads_pool.create_thread(boost::bind(&boost::asio::io_service::run,
&m_service));

                m_service.run();
        }

        void accept_handler(const boost::system::error_code &e, Session
*connection)
        {
                if(!e)
                {
                        connection->run();
                        accept();
                }
        }

protected:
        boost::asio::io_service m_service;
        boost::asio::ip::tcp::acceptor m_acceptor;
};

int main(int argc, char **argv)
{
        Server server(7070);
        server.run();
        return 0;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk