3

我正在尝试实现一个简单的 HTTP 服务器。我能够向客户端发送 HTTP 响应,但问题是在 Firefox 上我收到“连接重置”错误。IE 也失败了,而 Chrome 可以完美运行并显示我在响应中发送的 HTML。

如果我 telnet 到我的服务器,那么我会在响应之后收到“连接丢失”消息。因此,由此我得出结论,连接没有正确关闭。以下是代码中的重要片段。

类 TCPServer - 这将启动接受器 (boost::asio::ip::tcp::acceptor) 对象。

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

类 TCPConnection - 表示到客户端的 TCP 连接。这扩展了-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;
}

我应该提到的重要一点是,由于 TCPConnection 的对象是由“智能指针”指向的,所以当 TCPConnection::handleWrite 的执行完成时,就没有指向这个 TCPConnection 对象的指针了。所以在handleWrite 完成后立即调用TCPConnection 的析构函数。

4

1 回答 1

1

服务器不应关闭套接字。如果服务器关闭套接字并且客户端发送更多数据或接收队列中有数据,则客户端将收到导致此错误的 RST。见http://cs.baylor.edu/~donahoo/practical/CSockets/TCPRST.pdf

The HTTP server should read the entire client request or in the case of HTTP/1.1 the entire sequence of client requests. In this example it does not read any of the client request so there is data in the receive queue, so that the client receives a reset.

Drain the socket with a sequences of async_reads before closing - probably in the future you will want to actually parse the client request ;-)

于 2011-06-22T10:48:37.340 回答