I am trying to implement a simple HTTP server. I am able to send the HTTP response to clients but the issue is that on Firefox I get "Connection Reset" error. IE too fails, while Chrome works perfectly and displays the HTML I sent in the response.
If I telnet to my server then I get "Connection Lost" message, just after the response. So, from this I concluded that connection is not getting closed properly. Below are important snippets from the code.
class TCPServer - This initiates the acceptor (boost::asio::ip::tcp::acceptor) object.
void TCPServer::startAccept()
{
TCPConnection::pointer clientConnection =
TCPConnection::create(acceptor.io_service());
acceptor.async_accept(clientConnection->getSocket(),
boost::bind(&TCPServer::handleAccept, this, clientConnection,
boost::asio::placeholders::error));
}
void TCPServer::handleAccept(TCPConnection::pointer clientConnection,
const boost::system::error_code& error)
{
std::cout << "Connected with a remote client." << std::endl;
if (!error)
{
clientConnection->start();
startAccept();
}
}
class TCPConnection - Represents a TCP connection to client. This extends - public boost::enable_shared_from_this<TCPConnection>
TCPConnection::TCPConnection(boost::asio::io_service& ioService)
: socket(ioService)
{
}
TCPConnection::~TCPConnection(void)
{
std::cout << "TCPConnection destructor called." << std::endl;
}
TCPConnection::pointer TCPConnection::create(boost::asio::io_service& ioService)
{
return pointer(new TCPConnection(ioService));
}
tcp::socket& TCPConnection::getSocket()
{
return socket;
}
void TCPConnection::start()
{
//ASSUME outBuf has some data.. It is initialized elsewhere.
boost::asio::async_write(socket, boost::asio::buffer(*outBuf),
boost::bind(&TCPConnection::handleWrite, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
std::cout << "Transferring " << outBuf->size() << " bytes." << std::endl;
}
void TCPConnection::handleWrite(const boost::system::error_code& err, size_t bytesTransferred)
{
std::cout << "Sent " << bytesTransferred << " bytes. Error:: " << err << std::endl;
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
socket.close();
std::cout << "TCP connection closed." << std::endl;
}
One important point that I should mention is that since objects of TCPConnection are pointed to by 'smart pointers' so when execution of TCPConnection::handleWrite finishes then there are no pointers left to point at this TCPConnection object. So immediately after handleWrite finishes, the TCPConnection's destructor is called.