参考资料
<<linux内核网络栈源代码情景分析>>
socket常用函数概述
根据socket提供的常用的库函数,socket,read,write等函数,
执行的过程
inet协议的注册流程
在上文中分析过了在设备的初始化过程中,会调用sock_init函数初始化,在该函数中又会调用proto_init函数进行初始化,在proto_init函数中会调用inet对应的初始化函数inet_proto_init,该函数如下;
void inet_proto_init(struct net_proto *pro)
{
struct inet_protocol *p;
int i;
printk("Swansea University Computer Society TCP/IP for NET3.019\n");
/*
* Tell SOCKET that we are alive...
* ÏòSOCKETÄ£¿é×¢²áÐÒé´Ø
*/
(void) sock_register(inet_proto_ops.family, &inet_proto_ops); // 注册tcp/ip协议对应的协议操作函数
seq_offset = CURRENT_TIME*250;
/*
* Add all the protocols.
*/
for(i = 0; i < SOCK_ARRAY_SIZE; i++)
{
tcp_prot.sock_array[i] = NULL;
udp_prot.sock_array[i] = NULL;
raw_prot.sock_array[i] = NULL;
}
tcp_prot.inuse = 0;
tcp_prot.highestinuse = 0;
udp_prot.inuse = 0;
udp_prot.highestinuse = 0;
raw_prot.inuse = 0;
raw_prot.highestinuse = 0;
printk("IP Protocols: ");
for(p = inet_protocol_base; p != NULL;) // 添加协议到链表尾部
{
struct inet_protocol *tmp = (struct inet_protocol *) p->next;
inet_add_protocol(p);
printk("%s%s",p->name,tmp?", ":"\n");
p = tmp;
}
/*
* Set the ARP module up
*/
arp_init(); // arp模块初始化
/*
* Set the IP module up
*/
ip_init(); // ip模块初始化
}
首先会调用sock_register函数注册协议到列表pops中,
int sock_register(int family, struct proto_ops *ops)
{
int i;
cli(); // 禁止中断
for(i = 0; i < NPROTO; i++) // 遍历最大的协议包含数量
{
if (pops[i] != NULL) // 如果该位置内容不为空则下一个
continue;
pops[i] = ops; // 找到为空的位置,讲该函数操作方法设置进去
pops[i]->family = family; // 设置该协议的family
sti(); // 打开中断并返回
return(i);
}
sti(); // 打开中断
return(-ENOMEM); // 返回出错
}
此时我们查看传入的inet_proto_ops操作集合;
static struct proto_ops inet_proto_ops = {
AF_INET,
inet_create, // 创建
inet_dup,
inet_release, // 释放
inet_bind, // 绑定
inet_connect, // 连接
inet_socketpair,
inet_accept, // 接受
inet_getname,
inet_read, // 读数据
inet_write, // 写数据
inet_select, // 检查套接字
inet_ioctl,
inet_listen, // 监听队列
inet_send, // 发送数据
inet_recv, // 接受数据
inet_sendto,
inet_recvfrom,
inet_shutdown,
inet_setsockopt, // 设置socket配置参数