
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; }