接:::::::::::::::::::::::::::::::::::::::::
|应用层| 应用程序
————————————————————————————————————————————
| | |
| 表示层 --------- | BSD Socket 层 | socket.c 内核 |
| 会话层----------|INET Socket 层| af_inet.c ------------------------ |
| | | | | |
| 传输层 L5 |<---------- tcp.c| TCP | udp.c| UDP| '''| |
| | |
| 网络层 L4 | IP 层 | ip.c |
| | |
| 链路层 L3 | 设备接口层 | arp.c dev.c |
| | |
| | 硬件层 | 设备驱动程序 |
---------------------------------------------
|
物理层 | 网络设备物理接口层 | 硬件设备
----------------------------------------------
BSD Socket 层和 Inet Socket
层函数并不实际处理,只是进行检查后层层下调。调用下层函数通过socket结构中ops字段完成的。ops字段为proto_ops结构类型。inet
层对传输层的调用是通过sock结构的prot字段完成的。
如图所示,sock结构中的prot会因为协议不同而走不同路径。
struct proto_ops{
int family;
int (*create) (struct socket *sock,int protocol);
......
};
sock_create(int family, int type, int protocol, struct socket **res)
其中type 被赋值给sock->type = type;
SOCK_STREAM套接口 为TCP协议
套接口中的流与UNIX中管道的概念相近.
字节流中没有分界线,也没有边界;没有记录的长度工块的大小,在接收端也不存在分组的概念,在接收端获得的所有数据都返回到调用者的缓冲区中
有序性。
SOCK_DGRAM 为UDP协议
当我们不需要数据传输的绝对有序性时和有需要数据传输的可靠性时,可以考虑使用SOCK_DGRAM.
特性:
1)分组发送后,可能无序的到达接收端。
2)分组可以可能发生丢失。
3)数据报分组有尺寸的大小限制,如果超出,可能会无法传送。
4)分组可以在不建立连接的情况下被发送到远程进程,这就允许本地进程每次将消息发送给不同IP地址上的同样的端口。
SOCK_SEQPACKET
本套接口对于X.25和AX.25协议非常重要,它与SOCK_STREAM的差别:SOCK_STERAM不保留消息边界,而SOCK_SEQPACKET保留.
特性:
1)保留消息边界
2)数据字节的接收顺序与发送顺序一致
3)保证发送数据字节被无错地传送到接收端
4)数据是通过一对连接的套接口进行传送的
等等其他类型。
family在create 函数在sock_create()中 net_families[family]->create(sock,
protocol);
family为网域类型。每种网域都有net_proto_family数据结构,系统初始化时,指向相应网域的数据结构会填入数组
net_families[]中,否则系统不支持给定网域,通过数组中对应元素来指向初始化函数,此结构只在linux2.4中。在linux网络堆栈中
则为pops[]数组。在其中,直接将数据结构proto_ops赋值给pops。
inet_create()
|
kmalloc(sizeof( *sk), GFP_KERNEL)
分配数据结构类型sock,然后根据SOCK_XX类型来赋值,如TCP,prot = &tcp_prot。
下面为数据结构proto结构将进行对传输层操作的调用,然后初始化sock数据结构。
struct proto{
struct sk_buff *( *wmalloc(struct sock *sk, unsigned long size, int force, int priority);
struct sk_buff * (* rmalloc(struct sock *sk, unsigned long size, int force, int priority);
void (*wfree) (struct sock *sk, struct sk_buff *sk, unsigned long size);
void (*rfree) (struct sock *sk, struct sk_buff *sk, unsigned long size);
unsigned long (*rspace)(struct sock *sk);
unsigned long (*wspace )(struct sock *sk);
void (* close) (struct sock *sk, int timeout);
int (*read) (struct sock *sk, unsigned char *to, int len, int noblock, unsigned flags);
.........
};
对应TCP协议为tcp_proto,UDP协议为udp_proto.如果多个讨介子使用TCP协议就会有多个sock结构使用tcp_proto变量
的函数,内核对这种管理通过在ptoto结构中定义sock_array数组来解决,使用该协议的套结字对应的sock结构被插入sock_array数
组的链表中。其sock_array有256个元素,每个可以有256个链表,端口号可达65535个。
休息下。。。。。。
阅读(1323) | 评论(0) | 转发(0) |