Chinaunix首页 | 论坛 | 博客
  • 博客访问: 154524
  • 博文数量: 41
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 425
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-14 10:16
文章分类
文章存档

2011年(1)

2010年(5)

2009年(35)

我的朋友

分类: LINUX

2009-08-13 14:46:36

tcp.c文件的tcp_write_timeout函数

978计划工作组 2009-8-13

1函数源码

/*

 *    A write timeout has occurred. Process the after effects.

 */

 

static int tcp_write_timeout(struct sock *sk)

{

       /*

        *    Look for a 'soft' timeout.

        */

       if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))

              || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1))

       {

              /*

               *    Attempt to recover if arp has changed (unlikely!) or

               *    a route has shifted (not supported prior to 1.3).

               */

              arp_destroy (sk->daddr, 0);

              ip_route_check (sk->daddr);

       }

       /*

        *    Has it gone just too far ?

        */

       if (sk->retransmits > TCP_RETR2)

       {

              sk->err = ETIMEDOUT;

              sk->error_report(sk);

              del_timer(&sk->retransmit_timer);

              /*

               *    Time wait the socket

               */

              if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING )

              {

                     tcp_set_state(sk,TCP_TIME_WAIT);

                     reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);

              }

              else

              {

                     /*

                      *    Clean up time.

                      */

                     tcp_set_state(sk, TCP_CLOSE);

                     return 0;

              }

       }

       return 1;

}2函数用途

重传定时器发生超时时被调用,根据套接字当前状态以及超时次数对该套接字进行相应处理

3调用关系

4语句注释

4.1 if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))

              || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1))

sk->state套接字当前状态。

TCP_ESTABLISHED连接建立状态,双方进行正常的数据传送所处的状态。

TCP_RETR1是常数7,表示在丢弃本地数据包前尝试发送的次数。如果重传次数超过TCP_RETR1,则重新进行远端主机ARP请求,监测是否远端主机MAC 地址发生变换。

sk->retransmits重传次数。

4.2 arp_destroy (sk->daddr, 0);

       ip_route_check (sk->daddr);

sk->daddr:远端地址

0:如ATF_PERM标志位被设置表示这是一个用户设置的永久表项,那么此表项不能删除

arp_destroy删除一个arp_tables的一个表项,删除条件是与sk->daddr匹配

ip_route_check:此函数未实现

4.3 if (sk->retransmits > TCP_RETR2)

TCP_RETR2:是常数15,如果重传次数超出TCP_RETR2则直接丢弃发送的数据包,放弃发送

4.4  sk->err = ETIMEDOUT;

       sk->error_report(sk);

       del_timer(&sk->retransmit_timer);

sk->err:错误类型值

ETIMEDOUT:错误码,值为110,过时了的连接,可能是中间路由器坏等导致

error_report:回调函数,被初始化为def_callback1def_callback1的功能是将相关进程状态重新设置为TASK_RUNNING,使得进程具备调度的资格。

retransmit_timerTCP重传计时器

del_timer:删除重传计时器

4.5  if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING ) {

       tcp_set_state(sk,TCP_TIME_WAIT);

       reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);

TCP_FIN_WAIT1本地发送FIN(用于结束连接的)数据包后即进入该状态,等待对方的应答,此时发送通道被关闭,但仍可以继续接收远端发送的数据包。在接收到远端发送的对于FIN 数据包的应答后,将进入TCP_FIN_WAIT_2 状态。

TCP_FIN_WAIT2进入该状态表示本地已接收到远端发送的对于本地之前发送的FIN 数据包的应答。进入该状态后,本地仍然可以继续接收远端发送给本地的数据包。在接收到远端发送的FIN 数据包后(表示远端也已经发送完数据),本地将发送一个应答数据包,并进入TCP_TIME_WAIT 状态。

TCP_CLOSING如果通信双方同时发送FIN 数据包,即同时进行关闭操作,则双方将同时进入TCP_CLOSING状态。具体的,本地发送一个FIN 数据包以结束本地数据包发送,如果在等待应答期间,接收到远端发送的FIN 数据包,则本地将状态设置为TCP_CLOSING 状态。在接收到应答后,再继续转入到TCP_CLOSE_WAIT 状态。

TCP_TIME_WAIT该状态被称为2MSL 等待状态。如果在此期间接收到远端发送的FIN 数据包,则表示之前在TCP_FIN_WAIT_2 状态发送的ACK 应答数据包在传输中丢失或者长时间被延迟,从而造成远

端重新发送了FIN 数据包,此时重发ACK 应答数据包。一旦2MSL 时间到期,则将进入TCP_CLOSE 状态,即完成关闭操作

TIME_CLOSE此为定时类型,2MSL 定时,宏值为2,赋给socktimeout域。

TCP_TIMEWAIT_LEN:超时的时间长度,此值小于0则系统会给个默认值3,通常是60秒。

tcp_set_state:设置TCP的当前状态

reset_msl_timer:是一个宏函数,宏展开后是调用reset_timer函数,此函数将TCP_TIMEWAIT_LEN的值赋给计时器的expires,并把该sock结构的timer加到系统的计时器队列,如果在加入前已经在计时器队列那么需要先从队列中移出后再加入。

4.6  tcp_set_state(sk, TCP_CLOSE);

TCP_CLOSE关闭状态,一个新建的TCP 套接字起始将处于该状态。

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