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

2024-11-14 08:30:00
admin
原创
138
摘要:问题描述:我正在尝试学习 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 套接字连接在数据阶段没有某种非阻塞行为,那么它就会非常脆弱,因为如果错误的数据包遇到网络问题,程序就很容易无限期地“挂起”,而且你对此无能为力。)

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1142  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   96  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   87  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   95  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   92  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用