网络协议栈17:connect函数分解之网络层接收数据处理
链路层经过对上层协议的检查,把数据包上传到了对应的上层协议层,在这里,就是IP层协议。
数据到达IP层后,IP层需要进行相应的检查,判断后,才决定是否需要把数据上传到上层。下面就是IP层所需要做的事情.
1.首先检测数据包的IP首部是否正确,即对数据包的IP部分的IP首部长度,版本,数据包的大小进行检查,如果符合要求,则继续进行下面的步骤,不符合要求,则释放数据包,直接退出
2.检测IP首部是否包含了选项部分,方法就是查看IP首部的总长度字段是否大于IP首部的长度,如果是,则需要把选项部分解析,这个选项部分会在上传到上层协议时就告知是否有选项的。
3.检测数据包是否是一个分片数据,如果是一个分片数据,则需要分配一个空间,把这个数据包预存起来,同时等待所有数据包的到达后,把所有分片数据重组,才返回这个完整的数据包。如果不是,则直接返回,相当于等待所有分片数据并完成重组。
4.检测是否是多播的数据包,如果是多播的数据包,则再检测这个数据包是否在多播组中,如果是,就接收这个数据包,如果不是,则放弃接收。如何检测本地IP是否是多播组中的一员,主要是遍历当前设备的多播组链表,如当前设备所维护的多播组链表中是有本次传输的目的IP,则表示本IP是多播组的一员,可以接收数据。
5.检测本次数据包对应的上层协议,主要是遍历struct inet_protocol这个链表而得知,因为struct inet_protocol这个链表在系统初始化时,把igmp_protocol / icmp_protocol / udp_protocol / tcp_protocol 等等这些上层协议都链接好,现在只需要遍历,即可找到对以的上层协议,即可调用对应上层协议的接收函数来接收数据,对以connect函数,IP上面的协议就是TCP协议,其所对以的struct inet_protocol结构体:
static struct inet_protocol tcp_protocol = {
tcp_rcv, /* TCP handler */
NULL, /* No fragment handler (and won't be for a long time) */
tcp_err, /* TCP error control */
NULL, /* next */
IPPROTO_TCP, /* protocol ID */
0, /* copy */
NULL, /* data */
"TCP" /* name */
};
而接收函数就是tcp_rcv(),系统就是调用这个函数来接收IP上传的数据