socket是一个抽象层,表现为一组接口。
函数声明:
int socket(int domain, int type, int protocol);
地址族、协议族(domain)
linux下定义在 include/linux/socket.h:
AF-和PF-的值一一对应。
(引用)
The "AF_" prefix stands for "address family" and the "PF_" prefix stands for "protocol family". Historically, the intent was that a single protocol family might support multiple address families and that the PF_ value was used to create the socket and the AF_ value was used in socket addresses structures. But in actually, a protocol family supporting multiple address families has never been supported and the sys/socket.h header defines the PF_ value for a given protocol to be equal to the AF_ value for that protocol. While there is no guarantee that this equality between the two will always be true, should anyone change this for existing protocols, lots of existing code would break.
协议族对应 net_proto_family 结构体:
struct net_proto_family {
int family;
int (*create)(struct net *net, struct socket *sock,
int protocol, int kern);
struct module *owner;
};
如AF_INET(internet ip protocol) 对应的结构体是(af_inet.c):
static const struct net_proto_family inet_family_ops = { .family = PF_INET, .create = inet_create, .owner = THIS_MODULE, };
地址族的注册
sock_register 函数完成地址族的注册。
int sock_register(const struct net_proto_family *ops) {
...
rcu_assign_pointer(net_families[ops->family], ops);
...
}
static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly;
主要就是把net_proto_family结构加进net_families数组。
type
定义在include/linux/net.h:
inet_protosw
这个结构体定义了IP protocols (TCP/UDP/ICMP/IP) 的操作的集合。inetsw_protosw结构会加进inetsw_array数组中。
proto_ops 定义了bind、connect、accept等调用。
proto 和proto_ops的区别
两者负责不同的层的通信。proto_ops会被先调用。
protocol
表示协议类型,比如IPPROTO_IP、IPPROTO_TCP等。
0表示由内核选择合适的协议。
例如,socket(PF_INET,SOCK_STREAM,0) 调用,由于sock→type是SOCK_STREAM, 对应的inet_protosw是:
protocol就是IPPROTO_TCP.