[英]boost::asio fails to close TCP connection cleanly
I am trying to implement a simple HTTP server. 我正在尝试实现一个简单的HTTP服务器。 I am able to send the HTTP response to clients but the issue is that on Firefox I get "Connection Reset" error. 我能够将HTTP响应发送给客户端,但问题是在Firefox上我遇到“连接重置”错误。 IE too fails, while Chrome works perfectly and displays the HTML I sent in the response. IE也失败了,而Chrome完美运行并显示我在响应中发送的HTML。
If I telnet to my server then I get "Connection Lost" message, just after the response. 如果我telnet到我的服务器然后在响应之后收到“Connection Lost”消息。 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. class TCPServer - 这将启动acceptor(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();
}
}
class TCPConnection - Represents a TCP connection to client. class TCPConnection - 表示与客户端的TCP连接。 This extends - public boost::enable_shared_from_this<TCPConnection>
这扩展了 - 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. 我应该提到的一点是,由于TCPConnection的对象是由“智能指针”指向的,因此当TCPConnection :: handleWrite的执行完成时,没有指针指向此TCPConnection对象。 So immediately after handleWrite finishes, the TCPConnection's destructor is called. 所以在handleWrite完成后立即调用TCPConnection的析构函数。
The server should not close the socket. 服务器不应该关闭套接字。 If the server closes the socket and the client sends more data or there is data in the receive queue then the client will receive a RST causing this error. 如果服务器关闭套接字并且客户端发送更多数据或接收队列中有数据,则客户端将收到导致此错误的RST。 See http://cs.baylor.edu/~donahoo/practical/CSockets/TCPRST.pdf 见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. HTTP服务器应该读取整个客户端请求,或者在HTTP / 1.1的情况下读取整个客户端请求序列。 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 ;-) 在关闭之前用一系列async_reads排空套接字 - 可能在将来你想要实际解析客户端请求;-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.