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

2011年(1)

2010年(5)

2009年(35)

我的朋友

分类: LINUX

2009-08-25 15:24:03

tcp.c文件的tcp_select函数

978计划工作组 2009-8-25

1函数源码

/*

 *    Wait for a TCP event.

 *

 *    Note that we don't need to set "sk->inuse", as the upper select layers

 *    take care of normal races (between the test and the event) and we don't

 *    go look at any of the socket buffers directly.

 */

static int tcp_select(struct sock *sk, int sel_type, select_table *wait)

{

       if (sk->state == TCP_LISTEN)

              return tcp_listen_select(sk, sel_type, wait);

 

       switch(sel_type) {

       case SEL_IN:

              if (sk->err)

                     return 1;

              if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV)

                     break;

 

              if (sk->shutdown & RCV_SHUTDOWN)

                     return 1;

                    

              if (sk->acked_seq == sk->copied_seq)

                     break;

 

              if (sk->urg_seq != sk->copied_seq ||

                  sk->acked_seq != sk->copied_seq+1 ||

                  sk->urginline || !sk->urg_data)

                     return 1;

              break;

 

       case SEL_OUT:

              if (sk->err)

                     return 1;

              if (sk->shutdown & SEND_SHUTDOWN)

                     return 0;

              if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV)

                     break;

              /*

               * This is now right thanks to a small fix

               * by Matt Dillon.

               */

 

              if (sk->prot->wspace(sk) < sk->mtu+128+sk->prot->max_header)

                     break;

              return 1;

 

       case SEL_EX:

              if (sk->urg_data)

                     return 1;

              break;

       }

       select_wait(sk->sleep, wait);

       return 0;

}

2函数用途

用于处理各种探测类型,具体包括:SEL_INSEL_OUTSEL_EX

3调用关系

4语句注释

4.1  case SEL_IN:

              if (sk->err)

                     return 1;

              if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV)

                     break;

              if (sk->shutdown & RCV_SHUTDOWN)

                     return 1;                  

              if (sk->acked_seq == sk->copied_seq)

                     break;

              if (sk->urg_seq != sk->copied_seq ||

                  sk->acked_seq != sk->copied_seq+1 ||

                  sk->urginline || !sk->urg_data)

                     return 1;

SEL_IN:宏值为1,探测是否有数据可读取。

sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV连接建立期间,需返回0

RCV_SHUTDOWN:宏值为1,接收通道被关闭后所处的状态,即远端发送了FIN数据包,此时tcp_select函数应返回1

sk->acked_seq==sk->copied_seq:相等表无数据可读取,所以返回0

sk->acked_seq表示本地希望接收到的下一个数据序列号。

sk->copied_seq本地已被读取的最后一个数据的序列号加1

sk->urg_seq紧急数据序列号

sk->urginline:此标志位表示怎样对待紧急数据,如果该标志位被设置为1,则将紧急数据处理为普通数据。即在读取时,不再进行区别对待。

sk->urg_data:为1表接收到了紧急数据。

sk->urg_seq != sk->copied_seq

sk->acked_seq != sk->copied_seq+1

4.2 case SEL_OUT:

              if (sk->err)

                     return 1;

              if (sk->shutdown & SEND_SHUTDOWN)

                     return 0;

              if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV)

                     break;

              if (sk->prot->wspace(sk) < sk->mtu+128+sk->prot->max_header)

                     break;

              return 1;

SEL_OUT:宏值为2表示探测对应套接字发送缓冲区的空闲空间大小是否满足发送需求

SEND_SHUTDOWN:宏值为2发送通道关闭,即本地主动发送FIN 数据包

sk->prot->wspace(sk):返回发送缓冲区当前空闲空间大小

sk->mtu表示最大传输单元,是本地网络加于本地的数据包大小限制。

sk->prot->max_header最大链路层首部长度,tcp协议的max_header初始值是128

4.3 case SEL_EX:

SEL_EX:宏值为4此处表示是否接收到了紧急数据。

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