Open vislee opened 2 years ago
linux-0.98可能是最早支持tcp/ip的linux内核版本,该版本由Ross Biro开发,随着内核版本变迁,tcp/ip实现也跟着进行了升级迭代, 随后,Fred N. van Kempen在Ross Biro的基础上,改写了代码的主要部分,发不了Net-2版本。后来Alan Cox等人又对Net-2版本的代码进行了重构和扩充,发布了Net-3版本。而linux-1.2.0(net代码中的版本是1.1.93)应该已经是Net-3版本的代码的最早实现了。
在Linux0.98的代码里,通过fd查找socket时,还需要遍历sockets数组。该版本已经做了优化,不再遍历了。 并且,支持的协议族也是通过调用函数注册的,而不是硬编码到代码里了。 还是先来串一下代码调用流程。 在init/main.c文件的start_kernel函数中调用net/socket.c文件中的sock_init初始化网络子系统。 unix socket 则调用的是net/unix/sock.c文件中的unix_proto_init函数。 inet协议则是调用的net/inet/af_inet.c文件的inet_proto_init函数。
start_kernel
sock_init
unix_proto_init
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... */ // 注册网络协议族回调函数 (void) sock_register(inet_proto_ops.family, &inet_proto_ops); seq_offset = CURRENT_TIME*250; /* * Add all the protocols. */ for(i = 0; i < SOCK_ARRAY_SIZE; i++) { // tcp协议 tcp_prot.sock_array[i] = NULL; // udp协议 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: "); // net/inet/protocol.c文件中,定义了TCP、UDP、IMCP等协议 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(); /* * Set the IP module up */ ip_init(); }
当应用程序调用socket函数创建socket套接字fd时,实际上是调用了sock_socket函数,该函数根据协议族(domain)又调用了af_inet 文件中inet_proto_ops结构体中的inet_create函数。
sock_socket
inet_proto_ops
inet_create
应用程序调用bind时,实际调用了sock_bind 函数, 该函数根据协议族(domain)又调用了af_inet 文件中inet_proto_ops结构体中的inet_bind函数。
bind
sock_bind
inet_bind
c文件组织:net/socket.c -> net/inet/af_inet.c -> net/inet/tcp.c 头文件组织:net.h -> sock.h
概述
linux-0.98可能是最早支持tcp/ip的linux内核版本,该版本由Ross Biro开发,随着内核版本变迁,tcp/ip实现也跟着进行了升级迭代, 随后,Fred N. van Kempen在Ross Biro的基础上,改写了代码的主要部分,发不了Net-2版本。后来Alan Cox等人又对Net-2版本的代码进行了重构和扩充,发布了Net-3版本。而linux-1.2.0(net代码中的版本是1.1.93)应该已经是Net-3版本的代码的最早实现了。
代码
在Linux0.98的代码里,通过fd查找socket时,还需要遍历sockets数组。该版本已经做了优化,不再遍历了。 并且,支持的协议族也是通过调用函数注册的,而不是硬编码到代码里了。 还是先来串一下代码调用流程。 在init/main.c文件的
start_kernel
函数中调用net/socket.c文件中的sock_init
初始化网络子系统。 unix socket 则调用的是net/unix/sock.c文件中的unix_proto_init
函数。 inet协议则是调用的net/inet/af_inet.c文件的inet_proto_init
函数。当应用程序调用socket函数创建socket套接字fd时,实际上是调用了
sock_socket
函数,该函数根据协议族(domain)又调用了af_inet 文件中inet_proto_ops
结构体中的inet_create
函数。应用程序调用
bind
时,实际调用了sock_bind
函数, 该函数根据协议族(domain)又调用了af_inet 文件中inet_proto_ops
结构体中的inet_bind
函数。c文件组织:net/socket.c -> net/inet/af_inet.c -> net/inet/tcp.c 头文件组织:net.h -> sock.h
总结