Chinaunix首页 | 论坛 | 博客
  • 博客访问: 508694
  • 博文数量: 118
  • 博客积分: 2575
  • 博客等级: 大尉
  • 技术积分: 1263
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-27 09:37
文章分类

全部博文(118)

文章存档

2017年(11)

2016年(8)

2015年(1)

2014年(9)

2013年(7)

2012年(38)

2011年(14)

2010年(18)

2009年(12)

分类: BSD

2012-02-13 17:21:16

最近由于要在产品上使能TCP的keepalive功能,接合TCPIP详解V2,看了一下它的实现。实现的代码主要集中在tcp_timer_keep()函数中。主要的代码如下:

  1.     delta = TICKS - tp->t_rcvtime;
  2.     keeptime = tcp_keepidle;

  3.     if (delta < (ULONG)keeptime) {
  4.         keeptime = keeptime - delta;
  5.         goto out;
  6.     }

  7.     if ((priv_always_keepalive ||
  8.      tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE) &&
  9.      tp->t_state <= TCPS_CLOSING) {
  10.         if (delta >= tcp_keepidle + tcp_maxidle)
  11.             goto dropit;

  12.         tcpStat.tcps_keepprobe++;

  13.         templateMbuf = tcp_maketemplate (tp);
  14.         if (templateMbuf != NULL)
  15.          t_template = mtod (templateMbuf, struct tcptemp *);
  16.         if (t_template) {
  17.             tcp_respond(tp, t_template->tt_ipgen,
  18.                  &t_template->tt_t, (struct mbuf *)NULL,
  19.                  tp->rcv_nxt, tp->snd_una - 1, 0);
  20.             m_free (templateMbuf);
  21.         }

  22.         keeptime = tcp_keepintvl;
  23.     }

  24.     callout_reset(tp->tt_keep, keeptime, tcp_timer_keep, tp);
  25.     splx(s);

代码简介:对于已经建立的连接,tcp_keepidle时间运行一次keepalive的检查(全局keepalive打开或者socket上的keepalive打开),如果idle的时间超过tcp_keepidle就会发送keepalive的probe消息,如果tcp_keepidle+tcp_maxidle时间还没有接收到数据,则关闭连接)。tcp_maxidle是按照tcp_keepintvl发送包,一连9个包,都没有收到响应的时间。上面代码中delta就是实际的idle时间。

probe包的方式是给对方发送序列号落在对方接收窗口之外的tp->snd_una-1的0长度数据包,导致对方肯定要回答一个ACK(如果连接还活着)或者RST(如果对方已经复位过了)。

阅读(3625) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~