请问Asio怎么样正确关闭socket连接?


#1
  • 之前在不再读写的时候会使用这样的回调
void handle_close(const boost::system::error_code& ec)
        {
            if(!ec){
                socket_.shutdown(boost::asio::socket_base::shutdown_send);
           
                boost::asio::async_read(socket_,boost::asio::null_buffers(),
                        boost::bind(&Connection::handle_close,
                            shared_from_this(),
                            boost::asio::placeholders::error));
            }else if(ec == boost::asio::error::eof){
                socket_.shutdown(boost::asio::socket_base::shutdown_receive);
                socket_.close();
                LOG4CPLUS_DEBUG(LOG,LOG4CPLUS_TEXT("connection closed."));
            }else{
                LOG4CPLUS_ERROR(LOG,LOG4CPLUS_TEXT("error:"<<ec.message()));
            }
        }
  • 后来stackoverflow上建议这样
 socket_.shutdown(boost::asio::socket_base::shutdown_both);
 socket_.close();
  • 之后又有说只要这个对象是shared_ptr管理的,就不需要close,在conn对象析构的时候就会close

说以想请教一下正确的关闭方式


#2

shared_ptr管理的,如果连接关闭就意味着socket所在的对象撤销,那么就不需要调用close。 你的关闭连接姿势没有问题。

关于tcp连接的close,还要注意几点,那就是tcp连接close时的状态值,也就是说 在一个tcp连接中,如果它的tcp协议栈的recv缓冲(sk_receive_queue)未被用户进程处理,在这个socket被close的时候,tcp协议栈将会返回一个RST,如果这个socket已经把tcp协议栈的接收缓冲区的数据全部读取干净了,那么在这个socket被close时,将返回一个FIN.

这一点尤为重要,由其是在linux网络程序调试当中,时而FIN时而RST就会让人陷入迷茫,知道上面这一点,就会清楚的知道这个状态的不同,也对应了不同的情况。


#3

学习了 今天学习到了socket关闭还有这么多学问