热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么muduo中的shutdown没有直接关闭TCP连接?

今天收到一位网友来信:在simple中的daytime示例中,服务端主动关闭时调用的是如下函数序列,这不是只是关闭了连接上的写操作吗&#x

今天收到一位网友来信:

在 simple 中的 daytime 示例中,服务端主动关闭时调用的是如下函数序列,这不是只是关闭了连接上的写操作吗,怎么是关闭了整个连接?


void DaytimeServer::onConnection(const muduo::net::TcpConnectionPtr& conn)2: {3: if (conn->connected())4: {5: conn->send(Timestamp::now().toFormattedString() &#43; "/n");6: conn->shutdown();7: }8: }9: 10: void TcpConnection::shutdown()11: {12: if (state_ &#61;&#61; kConnected)13: {14: setState(kDisconnecting);15: loop_->runInLoop(boost::bind(&TcpConnection::shutdownInLoop, this));16: }17: }18: 19: void TcpConnection::shutdownInLoop()20: {21: loop_->assertInLoopThread();22: if (!channel_->isWriting())23: {24: // we are not writing25: socket_->shutdownWrite();26: }27: }28: 29: void Socket::shutdownWrite()30: {31: sockets::shutdownWrite(sockfd_);32: }33: 34: void sockets::shutdownWrite(int sockfd)35: {36: if (::shutdown(sockfd, SHUT_WR) <0)37: {38: LOG_SYSERR <<"sockets::shutdownWrite";39: }40: }

陈硕答复如下&#xff1a;

Muduo TcpConnection 没有提供 close&#xff0c;而只提供 shutdown &#xff0c;这么做是为了收发数据的完整性。

TCP 是一个全双工协议&#xff0c;同一个文件描述符既可读又可写&#xff0c; shutdownWrite() 关闭了“写”方向的连接&#xff0c;保留了“读”方向&#xff0c;这称为 TCP half-close。如果直接 close(socket_fd)&#xff0c;那么 socket_fd 就不能读或写了。

用 shutdown 而不用 close 的效果是&#xff0c;如果对方已经发送了数据&#xff0c;这些数据还“在路上”&#xff0c;那么 muduo 不会漏收这些数据。换句话说&#xff0c;muduo 在 TCP 这一层面解决了“当你打算关闭网络连接的时候&#xff0c;如何得知对方有没有发了一些数据而你还没有收到&#xff1f;”这一问题。当然&#xff0c;这个问题也可以在上面的协议层解决&#xff0c;双方商量好不再互发数据&#xff0c;就可以直接断开连接。

等于说 muduo 把“主动关闭连接”这件事情分成两步来做&#xff0c;如果要主动关闭连接&#xff0c;它会先关本地“写”端&#xff0c;等对方关闭之后&#xff0c;再关本地“读”端。练习&#xff1a;阅读代码&#xff0c;回答“如果被动关闭连接&#xff0c;muduo 的行为如何&#xff1f;” 提示&#xff1a;muduo 在 read() 返回 0 的时候会回调 connection callback&#xff0c;这样客户代码就知道对方断开连接了。

Muduo 这种关闭连接的方式对对方也有要求&#xff0c;那就是对方 read() 到 0 字节之后会主动关闭连接&#xff08;无论 shutdownWrite() 还是 close()&#xff09;&#xff0c;一般的网络程序都会这样&#xff0c;不是什么问题。当然&#xff0c;这么做有一个潜在的安全漏洞&#xff0c;万一对方故意不不关&#xff0c;那么 muduo 的连接就一直半开着&#xff0c;消耗系统资源。

完整的流程是&#xff1a;我们发完了数据&#xff0c;于是 shutdownWrite&#xff0c;发送 TCP FIN 分节&#xff0c;对方会读到 0 字节&#xff0c;然后对方通常会关闭连接&#xff0c;这样 muduo 会读到 0 字节&#xff0c;然后 muduo 关闭连接。&#xff08;思考题&#xff0c;在 shutdown() 之后&#xff0c;muduo 回调 connection callback 的时间间隔大约是一个 round-trip time&#xff0c;为什么&#xff1f;&#xff09;

另外&#xff0c;如果有必要&#xff0c;对方可以在 read() 返回 0 之后继续发送数据&#xff0c;这是直接利用了 half-close TCP 连接。muduo 会收到这些数据&#xff0c;通过 message callback 通知客户代码。

那么 muduo 什么时候真正 close socket 呢&#xff1f;在 TcpConnection 对象析构的时候。TcpConnection 持有一个 Socket 对象&#xff0c;Socket 是一个 RAII handler&#xff0c;它的析构函数会 close(sockfd_)。这样&#xff0c;如果发生 TcpConnection 对象泄漏&#xff0c;那么我们从 /proc/pid/fd/ 就能找到没有关闭的文件描述符&#xff0c;便于查错。

muduo 在 read() 返回 0 的时候会回调 connection callback&#xff0c;然后把 TcpConnection 的引用计数减一&#xff0c;如果 TcpConnection 的引用计数降到零&#xff0c;它就会析构了。



推荐阅读
  • 【CTF 攻略】第三届 SSCTF 全国网络安全大赛—线上赛 Writeup
    【CTF 攻略】第三届 SSCTF 全国网络安全大赛—线上赛 Writeup ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
  • 本文介绍了Windows Vista操作系统中的用户账户保护功能,该功能是为了增强系统的安全性而设计的。通过对Vista测试版的体验,可以看到系统在安全性方面的进步。该功能的引入,为用户的账户安全提供了更好的保障。 ... [详细]
  • ShiftLeft:将静态防护与运行时防护结合的持续性安全防护解决方案
    ShiftLeft公司是一家致力于将应用的静态防护和运行时防护与应用开发自动化工作流相结合以提升软件开发生命周期中的安全性的公司。传统的安全防护方式存在误报率高、人工成本高、耗时长等问题,而ShiftLeft提供的持续性安全防护解决方案能够解决这些问题。通过将下一代静态代码分析与应用开发自动化工作流中涉及的安全工具相结合,ShiftLeft帮助企业实现DevSecOps的安全部分,提供高效、准确的安全能力。 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • 本文探讨了容器技术在安全方面面临的挑战,并提出了相应的解决方案。多租户保护、用户访问控制、中毒的镜像、验证和加密、容器守护以及容器监控都是容器技术中需要关注的安全问题。通过在虚拟机中运行容器、限制特权升级、使用受信任的镜像库、进行验证和加密、限制容器守护进程的访问以及监控容器栈,可以提高容器技术的安全性。未来,随着容器技术的发展,还需解决诸如硬件支持、软件定义基础设施集成等挑战。 ... [详细]
  • 玩转直播系列之消息模块演进(3)
    一、背景即时消息(IM)系统是直播系统重要的组成部分,一个稳定的,有容错的,灵活的,支持高并发的消息模块是影响直播系统用户体验的重要因素。IM长连接服务在直播系统有发挥着举足轻重的 ... [详细]
  • 由于同源策略的限制,满足同源的脚本才可以获取资源。虽然这样有助于保障网络安全,但另一方面也限制了资源的使用。那么如何实现跨域呢,以下是实现跨域的一些方法。 ... [详细]
  • 【BP靶场portswigger服务端10】XML外部实体注入(XXE注入)9个实验(全)
    前言:介绍:博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章)。殊荣:CSDN网络安 ... [详细]
author-avatar
isme7
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有