1. 套接字创建与内核结构体的双向关联
当应用程序调用 socket()
系统调用时,内核会为该套接字分配一个 struct file
结构体,并初始化其中的 private_data
指针指向一个 struct socket
结构体。
同时,struct socket
中的 file
指针会反向指向这个 struct file
结构体。这种双向关联使得内核能够在需要时,在两者间进行导航。
2. 套接字结构体的层次与嵌套关系
在 Linux 内核中,不同类型的套接字(TCP / UDP)通过一系列嵌套的结构体来实现其特定的功能。
以下是这些结构体的层次关系和它们之间的嵌套方式:
// Kernel linux-2.6.24
struct sock;
struct inet_sock;
struct inet_connection_sock;
struct tcp_sock
{
/* inet_connection_sock has to be the first member of tcp_sock */
struct inet_connection_sock inet_conn;
// ...
};
struct inet_connection_sock {
/* inet_sock has to be the first member! */
struct inet_sock icsk_inet;
struct request_sock_queue icsk_accept_queue;
// ...
};
struct inet_sock {
/* sk and pinet6 has to be the first two members of inet_sock */
struct sock sk;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct ipv6_pinfo *pinet6;
#endif
// ...
};
struct udp_sock {
/* inet_sock has to be the first member */
struct inet_sock inet;
// ...
};
3. 套接字创建过程中的结构体分配与关联
当应用程序创建一个 TCP / UDP 套接字时,内核会分配相应的 tcp_sock
/ udp_sock
对象,这些对象包含了协议特定的状态和操作。
同时,内核会为该套接字分配一个唯一的文件描述符 sockfd
,并创建一个 struct file
结构体。
struct file
的 private_data
指针会指向一个新的 struct socket
结构体,该结构体中包含一个指向具体 tcp_sock
/ udp_sock
对象的 struct sock
指针。