`
liujianguangaaa
  • 浏览: 235188 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

关于socket心跳的实现

阅读更多

目前手头有个关于心博功能的一个案例, 在使用SOL_SOCKET, SO_KEEPALIVE上有一点心得,想写出来和大家分享一下。

关于SOL_SOCKET选项SO_KEEPALIVE有一个很详细的英文How TO, 在下面的网页中大家可以看到详细的内容
http://www.icewalkers.com/Linux/Howto/TCP-Keepalive-HOWTO/index.html

在《UNIX网络编程第1卷》中也有详细的阐述:

SO_KEEPALIVE 保持连接检测对方主机是否崩溃,避免(服务器)永远阻塞于TCP连接的输入。设置该选项后,如果2小时内在此套接口的任一方向都没有数据交换,TCP就自 动给对方 发一个保持存活探测分节(keepalive probe)。这是一个对方必须响应的TCP分节.它会导致以下三种情况:对方接收一切正常:以期望的ACK响应。2小时后,TCP将发出另一个探测分 节。对方已崩溃且已重新启动:以RST响应。套接口的待处理错误被置为ECONNRESET,套接 口本身则被关闭。对方无任何响应:源自berkeley的TCP发送另外8个探测分节,相隔75秒一个,试图得到一个响应。在发出第一个探测分节11分钟 15秒后若仍无响应就放弃。套接口的待处理错误被置为ETIMEOUT,套接口本身则被关闭。如ICMP错误是“host unreachable(主机不可达)”,说明对方主机并没有崩溃,但是不可达,这种情况下待处理错误被置为 EHOSTUNREACH。

在该书的第158页有更详细的描述。

根据上面的介绍我们可以知道对端以一种非优雅的方式断开连接的时候,我们可以设置SO_KEEPALIVE属性使得我们在2小时以后发现对方的TCP连接是否依然存在。

keepAlive = 1;
Setsockopt(listenfd, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepAlive, sizeof(keepAlive));

如果我们不能接受如此之长的等待时间,从TCP-Keepalive-HOWTO上可以知道一共有两种方式可以设置,一种是修改内核关于网络方面的 配置参数,另外一种就是SOL_TCP字段的TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT三个选项。


The tcp_keepidle parameter specifies the interval of inactivity that causes TCP to generate a KEEPALIVE transmission for an application that requests them. tcp_keepidle defaults to 14400 (two hours).

/*开始首次KeepAlive探测前的TCP空闭时间 */

The tcp_keepintvl parameter specifies the interval between the nine retries that are attempted if a KEEPALIVE transmission is not acknowledged. tcp_keepintvl defaults to 150 (75 seconds).
/* 两次KeepAlive探测间的时间间隔  */


The TCP_KEEPCNT option specifies the maximum number of keepalive probes to be sent. The value of TCP_KEEPCNT is an integer value between 1 and n, where n is the value of the systemwide tcp_keepcnt parameter.

/* 判定断开前的KeepAlive探测次数 */

因此我们可以得到
int                 keepIdle = 6;
int                 keepInterval = 5;
int                 keepCount = 3;

    Setsockopt(listenfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle));

    Setsockopt(listenfd, SOL_TCP,TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));

    Setsockopt(listenfd,SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

我们需要注意的TCP-Keepalive-HOWTO上这段话:

Remember that keepalive is not program−related, but socket−related, so if you have multiple sockets, you can handle keepalive for each of them separately.

这些属性是sockt继承的,非整个代码内的所有sockets都继承这个属性,因为如果要应用到多个套接口上必须分别使用Setsockopt, Setsockopt是setsockopt的包裹函数。

如果心搏函数要维护客户端的存活,即服务器必须每隔一段时间必须向客户段发送一定的数据,那么使用SO_KEEPALIVE是有很大的不足的。因为 SO_KEEPALIVE选项指"此套接口的任一方向都没有数据交换",我不知道大家是怎么理解这个实现的。在Linux 2.6系列上,上面话的理解是只要打开SO_KEEPALIVE选项的套接口端检测到数据发送或者数据接受就认为是数据交换。

因此在这种情况下使用 SO_KEEPALIVE选项 检测对方是否非正常连接是完全没有作用的,在每隔一段时间发包的情况, keep-alive的包是不可能被发送的。上层程序在非正常端开的情况下是可以正常发送包到缓冲区的。非正常端开的情况是指服务器没有收到"FIN" 或者 "RST"包。

当然这种情况也是比较好断定对方是否存活,我提出来的主要原因是想看看大家对"此套接口的任一方向都没有数据交换"是怎么去理解的。

分享到:
评论

相关推荐

    socket心跳功能

    在此,我们将深入探讨Socket心跳机制、其在Java中的实现以及心跳包的作用。 首先,Socket是基于TCP协议的编程接口,提供了低级别的、原始的网络通信能力。在TCP连接中,如果一方长时间没有发送数据,另一方可能会...

    java Socket心跳事例

    在这个“java Socket心跳事例”中,我们将会深入探讨如何使用Java的Socket编程来实现心跳机制,这是一种确保连接可靠性和有效性的常见策略。 心跳机制的基本思想是,两个通信端点定期交换信息,以确认连接仍然有效...

    Socket心跳测试Java版

    DemoSocket项目很可能是提供了一个完整的Socket心跳测试示例,包含了上述所有环节的实现,便于开发者理解和学习。 总的来说,Java Socket通信的心跳测试是确保长时间运行的网络服务稳定性的关键手段,通过定期交换...

    C# 实现Scoket心跳机制的方法

    下面是一个简单的心跳实现的示例代码: ```csharp using System; using System.Collections.Generic; using System.Threading; namespace ConsoleApplication1 { // 客户端离线委托 public delegate void ...

    socketTCP通信心跳包实例

    在Winform应用中实现socket心跳包,通常包括以下几个步骤: 1. 创建Socket对象:在C#中,使用`System.Net.Sockets.Socket`类创建一个Socket实例,指定协议类型为TCP(`SocketType.Stream`)和IP协议族(`...

    Socket心跳连接_java

    本篇文章将深入探讨Java中的Socket心跳连接以及其在TCP长连接中的应用。 首先,TCP是一种面向连接的、可靠的传输协议,它通过三次握手建立连接,并在数据传输完成后通过四次挥手释放连接。然而,在某些应用中,如...

    Socket长连接心跳

    以上就是关于Socket长连接心跳的主要内容。通过合理设计和实现心跳机制,可以显著提升网络连接的稳定性和用户体验。在实际项目中,还需要根据具体业务需求进行优化和调整。提供的`SocketSe`和`SocKetCli`可能分别是...

    Socket长连接+心跳包+发送读取

    3. **心跳机制**:心跳包的设计和实现,包括心跳间隔时间、心跳包内容、超时策略、重试机制等。心跳包可以防止网络阻塞导致的假死,以及及时发现并处理真正的连接中断。 4. **数据编码与解码**:发送的数据通常需要...

    winform socket通讯和心跳包

    6. **实现心跳包机制**:在Winform Socket通信中,心跳包通常由服务器或客户端定时发送。这些包包含简短的信息,比如“心跳”或特定的标识符,表明发送方仍在工作并监听连接。 7. **心跳包间隔和超时设定**:设定...

    C#使用Socket实现心跳的方法示例

    "C#使用Socket实现心跳的方法示例" C#使用Socket实现心跳的方法示例是指通过使用Socket编程来实现心跳机制的方法。心跳机制是指在网络通信中,通过定期发送心跳包来维持连接的机制,以避免连接超时或断开。 在C#中...

    Android的socket长连接(心跳检测)

    以上就是关于Android的Socket长连接和心跳检测的相关知识点。实际开发中,还需要根据项目需求进行相应的优化和调整,例如使用线程池管理连接,或者使用更高级的网络库如OkHttp、Retrofit等来简化网络操作。

    Android-Socket长连接通信心跳包消息回调Java服务端

    本主题将深入探讨如何实现“Android-Socket长连接通信心跳包消息回调Java服务端”的技术细节。 首先,我们需要理解Socket通信的基本原理。Socket是网络编程中的一个概念,它为应用程序提供了一种在两台机器间建立...

    C# socket通信项目,实现了实现了心跳、断线重连、服务端异步接收数据、消息回调反馈、解决了粘包相关问题,可以多客户端

    3、socket功能类库模块(其他项目也可以引用),socket类库模块功能齐全,只需调用其中方法即可,复用性较强,代码注释详细,实现了心跳,解决了粘包问题,异步发送接收数据,等等,bin目录下右运行日志方便查找程序...

    TCP长连接Socket心跳收发消息

    实现TCP长连接Socket心跳收发消息的过程通常包括以下步骤: 1. 建立TCP连接:客户端发起连接请求,服务器响应,完成三次握手。 2. 设置心跳间隔:双方协商并设置合适的心跳间隔时间,比如30秒或60秒。 3. 发送心跳...

    C#之实现Scoket心跳机制

    C#高级编程之实现Socket心跳机制,TCP网络长连接。 心跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么...

    Java心跳包功能实现

    本项目实现了心跳包的发送和接收功能,包括客户端和服务端的完整实现。 **心跳包的基本原理** 心跳包的原理是客户端和服务端周期性地交换数据包,即使没有实际业务数据需要传输,也会发送一个空的数据包。如果一方...

    socket心跳测试(java)

    本篇将详细探讨如何使用Java进行socket通信,特别是实现心跳检测机制,以确保长连接的稳定性和可靠性。 首先,我们需要理解“心跳”在计算机网络中的含义。心跳检测是一种机制,用于检查网络连接是否仍然活跃。在...

    C#高性能服务器;端口-心跳高性能Socket服务器

    本篇将深入探讨"端口-心跳高性能Socket服务器"的设计与实现,以及C#在此领域的应用。 首先,Socket是网络编程的基础,它提供了进程间通信(IPC)的能力,使得不同计算机上的程序能够相互通信。在C#中,System.Net....

    vb.net通过socket实现简易多人聊天室(含心跳检测机制)

    语言vb.net (c#可以参考)+winform开发,利用socket进行多个客户端通信实现简易的聊天室,为了保证客户端与服务端连接正常,增加心跳检测机制、客户端定时断开超时未发送心跳包的客户端机制。 界面比较粗糙,仅供学习...

    Socket通信 心跳重连

    文件名"SocketTest"可能是一个示例程序,用于演示如何实现Socket通信的心跳重连功能。在这个程序中,可能会包括创建Socket实例、设置心跳包定时器、心跳包的发送与接收逻辑,以及重连机制的实现。 总结来说,Socket...

Global site tag (gtag.js) - Google Analytics