• 传说中的成大大 置顶
    2019-08-28
    思考题
    1. udp不需要连接 所以没有必要心跳包
    2. 我觉得还是很有必要判定存活 像以前网吧打游戏 朋友的电脑突然蓝屏死机 朋友的角色还残留于游戏中,所以服务器为了判定他是否真的存活还是需要一个心跳包 隔了一段时间过后把朋友角色踢下线

    作者回复: 2是一个很好的例子。

     1
     3
  • fjpcode
    2019-08-28
    1.UDP里面各方并不会维护一个socket上下文状态是无连接的,如果为了连接而保活是不必要的,如果为了探测对端是否正常工作而做ping-pong也是可行的。
    2.额外的探活报文是会占用一些带宽资源,可根据实际业务场景,适当增加保活时间,降低探活频率,简化ping-pong协议。
    3.多次探活是为了防止误伤,避免ping包在网络中丢失掉了,而误认为对端死亡。

    作者回复: 👍

     1
     11
  • 徐凯
    2019-09-06
    老师 同步连接可以实现心跳包么 如果不能的话 那同步连接如果因为客户端崩溃 没有通过四次挥手结束连接 服务端还堵塞在接收数据 那么这样如何判断对方已经离开呢

    作者回复: 首先,客户端应用程序崩溃是可以有FIN包的,如果有的话,read阻塞就可以返回了;其次,如果真的是客户端机器跪了,那么是没有FIN包发出的,这个时候,我们只好一直在那里傻等。

    且慢,还有别的辙,那就是不要用阻塞I/O,不要在哪里傻傻等待。使用I/O复用就可以办到的,往后看就会明白了。

     1
     3
  • 云师兄
    2019-12-17
    文章中提到保活有两个方向,实际应用中,会有两个方向同时探测的场景吗

    作者回复: 当然有。服务器端要探活client来保证自己不会维护无效连接,客户端来探活保持自己是不是可以持续申请资源。

    
     1
  • 衬衫的价格是19美元
    2019-10-04
    tcp探活的目的之一是判断该连接是否还需要,以此决定是维持还是释放该连接资源。udp无连接,也不占用服务器或者客户端的资源,因此业务无需探活
    
     1
  • Geek_d6f50f
    2020-01-05
    老师,第二次运行程序,客户端的定时器设定为每10秒钟进行一次select返回0,此时进行探测包发送。而服务器端延迟5秒进行应答,为什么客户端每次都能发送两个包后才清零?不应该是只进行一个包的发送,服务器端延迟5秒就给出应答,然后清零吗?

    作者回复: 是这样的,

    当客户端10秒钟select超时时间到达,第一次进入heartbeat,发送报文给服务器端,同时客户端把下一次select超时时间设置为3秒(KEEP_ALIVE_INTERVAL);

    由于服务器端是5秒之后才回复,3秒之后,第二次heartbeat时间到,客户端发送第二个heartbeat。

    5秒之后,第一次的heartbeat回复到,客户端把超时时间又重新设置为10秒。

    再过5秒之后,第二次的heartbeat回复到,客户端把超时时间再次设置为10秒。

    如此反复。

    
    
  • A.Windy
    2020-01-02
    看到后面就知道了, 嘿嘿 https://github.com/froghui/yolanda
    
    
  • A.Windy
    2020-01-02
    程序编译不过, 说lib/common.h 找不到, 怎么搞啊

    作者回复: 应该搞定了吧

     1
    
  • motorlei
    2019-12-20
    老师 我想问一下 看您在回复当中有说 虽然TCP本身的keep-alive机制可以设置保活时间,保活探测时间间隔以及探测次数,但是应用层会无法感知,那么这种情况下会怎么处理呢 就是文中所给出的三种情况吗

    作者回复: 是的,大部分的应用程序开发者都会选择自己在应用层处理连接有效性的检测。

    
    
  • HunterYuan
    2019-12-17
    对于协议栈中的TCP的keep-alive是可以手动配置的,全局配置通过修改net.ipv4下的等参数;局部配置可以通过setsockopt修改socket选项。在工作中遇到过一个oracle,windows服务器的保活时间大于,我们设备状态连接表的保活时间,导致,一段时间后重连,导致服务器报错问题。当时最最快的处理办法是,修改window默认的保活时间小于状态连接失效时间。

    作者回复: 学习了。

    
    
  • 我叫徐小晋
    2019-12-04
    老师您好,这个保活时间是指一个定时器,到了这个时间会发送一个ping消息。
    保活时间间隔是什么?

    作者回复: 保活时间间隔就是每隔多长时间发送类似的ping消息。定时器是保活实现的一种常见形式。

    
    
  • bbbi
    2019-12-01
    我的理解是这样的:
    TCP协议并没有提供一个保活的措施,如果出现TCP已经连接后,两端异常崩溃或者是编码问题没有及时的关闭连接(比如客户端发送-->服务端收到消息返回数据-->客户端收到后直接退出,没有调用close),那么服务器会一直维护着这个通道,造成资源浪费。所以加入keepalive,系统提供一个计时器,在约定的时间下发送检测包。但是这个计时器检测时间默认是2小时开始检测时间太长,所以我们可以在应用层,手动发送检测包

    作者回复: 基本是这样。而且应用层处理的时候,还有各种异常处理,便于暴露和发现问题,如果是使用tcp协议的keepalive,不是很容易处理这些细节。

     1
    
  • godtrue
    2019-11-23
    探测TCP连接是否有效,KEEP-ALIVE可以实现,不过时间太长啦!所以,通常会在应用层,自己仿照KEEP-ALIVE的原理弄一个自己更加可以灵活可控的。
    
    
  • zhan
    2019-10-26
    这程序,没看懂。。。

    作者回复: 哪里没看懂?

    
    
  • 15652790052
    2019-10-08
    请教一个问题: 客户端如果奔溃了->进程退出了->内核会收到关于此进程的所有资源,包括socket文件->意味这个socket的两个方向都关闭了,怎么会感知不到而傻等呢

    作者回复: 这种情况下确实不会傻等。

    
    
  • 陈诚
    2019-09-28
    如果能收到服务器端的应答,则结束保活,将保活时间置为 0。

    --->
    如果能收到服务器端的应答,则结束保活,将保活时间置为KEEP_ALIVE_TIME,即恢复初值
    
    
  • 有点意思
    2019-09-25
    老师 你好
    现在做的项目中要用到心跳,具体是这样的
    服务端一个 客户端多个
    每个客户端会持续的往服务端发送从网卡抓取的流量,如果某段时间网卡没有流量就不发 但是连接还需要维持 之前用的keepalive 现在想换成应用层心跳
    想到的方案如下:
    客户端开启线程1来发送抓到的流量 并且每间隔1秒就发送一次心跳给服务端 服务端收到心跳会回复一下
    同时开启另外一个线程2启用select和recv来接收心跳响应 如果在 3秒内没接受到心跳 那么就判断连接断开

    老师你觉得这种方案可以么 有什么缺点么
    展开

    作者回复: 每秒一次会不会太快了?

     2
    
  • 冷雨
    2019-09-11
    第一题:udp可以使用同样的方式
    第二题:确实占用带宽,但一方面ping-pong报文大小比较小,带宽占用有限,另一方面及时确认连接是否可用比带宽的损耗要重要的多。为什么要多次才能确认呢,因为网络抖动可能导致ping消息没有收到或者pong消息没有返回,如果一次就关闭,很容易导致误杀,而且socket建立的成本也比较高,多次确认对应用程序来说也是可以接受的。
    
    
  • Rancood
    2019-09-10
    UDP本身就是无连接的,不需要探活;现在带宽可以忽略不计了,有时候可能因为网络原因报文不可达,所以需要多试几次
    
    
  • 另一半棉花糖
    2019-09-09
    在对端计算能力紧张、或者网络延迟比较大的时候,仍然会对每一个ping包都做回复,但是本端可能在发了第KEEP_ALIVE_PROBETIMES-1个包之后才收到对端针对第一个ping做的回复。这样虽然本端就会认为这个连接是有效的,但会在接下来接收到好几个pong包;如果这一批的某一个pong包的到来时间正好落在本端第二次由于select超时而进行链路探测的时间段内的话,则可能产生“对端实际已经down了,但是本端过很久才能检测到(可能要达到N个select超时时间)”的问题。这个问题该怎么解决?要给ping和pong加序列号以用于匹配么?

    作者回复: 这个是你工作中碰到过的,还是你自己构想出来的案例?

    本质上,你问的问题是网络有延迟,导致检测时间也有延迟,我觉得这个是完全正常的,因为我们的程序是"企图"发现对端是否down掉了,是一个后知后觉型的,肯定是需要时间判断的。一般我们可以通过设置这个N的值来进行调整。比如N=3,三个包不回就认为down掉了。

    
    
我们在线,来聊聊吧