网络协议栈11:Connect函数分解之TCP层

Connect函数之分解1.

首先,connect函数从参数获得远端的IP,把这个地址赋值给对应的sock结构体的对应变量,并设置了sock结构体中的一些其他变量后,首先分配(skb_buff+用户空间)大小内存,这两部分是通过调用kmalloc(sizeof(struct skb_buff)+size,priority)来分配的,分配后两个数据块是连续的地址;分配后的内存如下

 

接下来,就是初始化这个刚刚分配好的skb_buff结构体的一些指针成员,之后,把整个数据空间的首地址返回给一个skb_buff指针,以后对skb结构体的操作,就通过这个指针来完成了。接着,把skb_buff跟sock关联起来,即把skb_buff的成员sk设置为对应的sock,路由指向本地路由,就开始配置通信数据了。

 

第一步,把指针指向skb_buff空间的数据空间,即skb_buff的成员data所指向的地址(上图 5)。

第二步(上图 1),设置以太网头部(本地MAC地址6字节+远端MAC地址6字节+数据帧类型2字节),把本地MAC地址复制到数据空间的开始处,本地的MAC地址,是从本地路由中获得,而目的MAC地址一般为NULL,如果为NULL,则需要设置skb_buff成员arp为0,表示远端MAC地址(或者下一跳MAC地址)并不知道,需要在发送数据之前使用ARP来查找,数据帧可以选择:

#define ETH_P_LOOP  0x0060           /* Ethernet Loopback packet  */

#define ETH_P_ECHO  0x0200           /* Ethernet Echo packet        */

#define ETH_P_PUP     0x0400           /* Xerox PUP packet            */

#define ETH_P_IP 0x0800           /* Internet Protocol packet    */

#define ETH_P_ARP     0x0806           /* Address Resolution packet */

#define ETH_P_RARP      0x8035          /* Reverse Addr Res packet   */

#define ETH_P_X25     0x0805           /* CCITT X.25                     */

#define ETH_P_ATALK 0x809B          /* Appletalk DDP          */

#define ETH_P_IPX      0x8137           /* IPX over DIX                  */

#define ETH_P_802_3   0x0001           /* Dummy type for 802.3 frames  */

#define ETH_P_AX25   0x0002           /* Dummy protocol id for AX.25  */

#define ETH_P_ALL     0x0003           /* Every packet (be careful!!!) */

#define ETH_P_802_2   0x0004           /* 802.2 frames            */

#define ETH_P_SNAP  0x0005           /* Internal only             */

 

第三步,指针跳过以太网首部14字节,指向IP首部(上图 2),跟着就是数据空间初始化IP首部,IP首部的数据基本上在sock结构体中都有用,现在只是从sock结构体复制过来,初始化完后,在skb_buff中还有一个专门的指针指向数据空间的IP首部的地址的成员ip_hdr,此时也初始化一下。

 

第四步,指针跳过IP首部,指向TCP首部(上图 3),跟着初始化数据空间的tcp首部,tcp首部一些是从sock结构体中复制的,一些是在这里第一次被赋值的,注意tcp首部不包含tcp选项部分,因此,需要把指针跳过tcp首部后,指向tcp的选项部分,进行初始化,才算把tcp初始化完成(把MSS赋值到选项部分)(上图 4)。

 

到此,我们就把数据空间初始化完,我们在开始时分配数据空间大小为44+18,现在使用的是14(MAC)+20(TCP)+20(IP)+4(MSS),也就用完了,从这里,我们看到,connect函数发送的数据,都是本地的一些信息,包装到MAC,TCP,IP等结构体中,目的是告知远端本地的一些情况的信息,以后通信时,就按照现在发送的规格进行了,而真正的数据部分是没有的。

 

最后,就是把数据发送的网络层,进行排队了。

posted on 2012-01-11 18:42  image eye  阅读(875)  评论(0编辑  收藏  举报