如何正确使用SO_KEEPALIVE选项来检测另一端的客户端是否已关闭?

2024-11-14 08:30:00
admin
原创
17
摘要:问题描述:我正在尝试学习 Linux 环境下使用 C 语言进行套接字编程时 SO_KEEPALIVE 选项的用法。我创建了一个服务器套接字并使用浏览器连接到它。连接成功了,我能够读取 GET 请求,但在 SO_KEEPALIVE 的使用上遇到了困难。我检查了此链接keepalive_description@t...

问题描述:

我正在尝试学习 Linux 环境下使用 C 语言进行套接字编程时 SO_KEEPALIVE 选项的用法。

我创建了一个服务器套接字并使用浏览器连接到它。连接成功了,我能够读取 GET 请求,但在 SO_KEEPALIVE 的使用上遇到了困难。

我检查了此链接keepalive_description@tldg.org,但找不到任何说明如何使用它的示例。

一旦我检测到客户端对accept()函数的请求,我就会设置客户端套接字上的SO_KEEPALIVE选项值1。现在我不知道如何检查客户端是否已关闭,如何更改发送探测之间的时间间隔等。

我的意思是,我如何才能得到客户端关闭的信号?(无需在客户端读取或写入 - 我认为当客户端没有回复探测时我会收到一些信号),在设置选项 SO_KEEPALIVE 后我应该如何对其进行编程)。

另外,如果假设探测每 3 秒发送一次,而客户端在其间关闭,那么我将无法知道客户端已关闭,并且可能会收到 SIGPIPE。

无论如何,重要的是我想知道如何在代码中使用 SO_KEEPALIVE。


解决方案 1:

要修改探测次数或探测间隔,可以将值写入 /proc 文件系统,例如

 echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
 echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
 echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes

请注意,这些值对于系统上所有启用 keepalive 的套接字都是全局的,您还可以在设置 setsockopt 时在每个套接字上覆盖这些设置,请参阅您链接的文档的第 4.2 节。

您无法使用 keepalive 从用户空间“检查”套接字的状态。相反,内核只是更积极地强制远程端确认数据包,并确定套接字是否已损坏。当您尝试写入套接字时,如果 keepalive 确定远程端已关闭,您将收到 SIGPIPE。

解决方案 2:

如果您启用 SO_KEEPALIVE,您将获得相同的结果,就好像您不启用 SO_KEEPALIVE 一样 - 通常您会发现套接字已准备就绪,但在读取时会收到错误。

您可以在 Linux 下按每个套接字设置 keepalive 超时(这可能是 Linux 特有的功能)。我建议这样做,而不是更改系统范围的设置。有关更多信息,请参阅 tcp 的手册页。

最后,如果您的客户端是 Web 浏览器,它很可能会很快关闭套接字 - 大多数客户端只会在相对较短的时间内(30 秒、1 分钟等)保持保持活动(HTTP 1.1)连接打开。当然,如果客户端计算机消失或网络中断(这正是 SO_KEEPALIVE 真正有用的检测方法),那么它将无法主动关闭套接字。

解决方案 3:

简短回答,添加

int flags =1;
if (setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags))) { perror("ERROR: setsocketopt(), SO_KEEPALIVE"); exit(0); };

在服务器端,read()当客户端关闭时,将会解除阻塞。

完整解释可在此处找到。

解决方案 4:

正如前面所讨论的,SO_KEEPALIVE 使内核更积极地持续验证连接,即使您没有执行任何操作,但不会改变或增强向您传递信息的方式。当您尝试实际执行某项操作(例如“写入”)时,您会发现这一点,而且您会立即发现,因为内核现在只是报告先前设置的标志的状态,而不必等待几秒钟(在某些情况下甚至更长)网络活动失败。您用于处理“另一方意外离开”情况的完全相同的代码逻辑仍将使用;改变的是时间(而不是方法)。

几乎每个“实用”套接字程序都会以某种方式在数据阶段提供对套接字的非阻塞访问(可能使用 select()/poll(),或者可能使用 fcntl()/O_NONBLOCK/EINPROGRESS&EWOULDBLOCK,或者如果您的内核支持,可能使用 MSG_DONTWAIT)。假设出于其他原因已经这样做了,那么立即发现连接断开是很简单的(有时根本不需要代码)。但是,如果数据阶段尚未以某种方式提供对套接字的非阻塞访问,您将不会发现连接断开,直到下次尝试执行某项操作时。

(如果 TCP 套接字连接在数据阶段没有某种非阻塞行为,那么它就会非常脆弱,因为如果错误的数据包遇到网络问题,程序就很容易无限期地“挂起”,而且你对此无能为力。)

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用