接:
这里不得不介绍一些概况一些重要数据结构。
struct socket{
short type; // 如上文。
socket_state state;
//插口的状态:SS_UNCONNECTED,SS_CONNECTED,SS_CONNECTING,SS_DISCONNECTED,第一个未连
接(初始化时的状态),第二个为已经建立连接,第三个为连接正在被处理,最后为取消连接。//
long flags; // SO_ACCEPTION 用于未连接socket,而且他们的进程在等待一个连接请求。其他SO_NOSPASE,SO_WAITDATA 表示不正常。
struct proto_ops *ops; //如上所示。
void *data; 保存私有数据。对于不同域的该指针指向不同数据结构。UNIX域指向unix_proto_data数据结构,INET指向sock数据结构。
struct socket *conn;
struct socket *iconn;两个字段仅对UNIX域有意义。
struct socket *next; 构成socket结构链表。
struct wait_queue **wait; 等待队列。
struct inode *inode; 上文中创建的inode结构,在sock_socket->sock_create()->sock_alloc()中。
struct fasync_struct *fasync_list; fasync_struct构成的链表,用于同步文件读写。
}
补充域协议协议初始化
域协议 初始化函数 说明
UNIX” unix_proto_init 本机进程间模拟网络的数据一种交换形式
"INET” inet_proto_ini 使用TCP/IP 协议族的网络数据包交换协议
"802.2” p8022_proto_init 使用 802.2 协议 局域网数据包定义标准。
"SNAP” snap_proto_init 使 用 SNAP ( Subnetwork
Access Protocol)协议
"AX.25” ipx_proto_init “IPX” ipx_proto_init 使用 IPX 网络层协议进行数据包交换 Novell 网络协议)
“DDP” atalk_proto_init AppleTalk
使用struct net_proto数据结构
struct net_proto{
char *name //域协议名称。
void (*init_func) (struct net_proto*); /指针
}
初始化
struct net_proto protocols[] =
#ifdef CONFIG_UNIX
{"UNIX", unix_proto_init},
#endif
........
};
举例在linux堆栈1.2.13中
inet_proto_init函数定义在/net/inet/af_inet.c中
调用 inet_proto_add;
进行传输层与网络层的连接。具体将inet_proto_base全局变量指向的inet_protocol结构队列中元素散列到struct
inet_proto *inet_protos[]中,被网络层调用。inet_protol结构为一个传输层协议,定义了传输层协议号和接受函数。
数据包传送通道
| 硬件监听物理传输介质 |
|
|完全接受一个数据包
|产生中断
|
|系统调用驱动程序中断处理函数处理 |
|
数据从硬件到内核复制 | 封装为特定数据结构sk_buff,调用链路层函接口函数netif_rx
| 将数据包暂存到内核维护的一个数据包队列backlog指向。
|
|
|启动下半部处理函数net_bh|
|从backlog队列中取数据包,进行本层处理后。
|便利ptype_base指向的网络协议层队列,进行协议号匹配。调用接受函数。如ARP协议,调用arp_rcv函数,网络层调用ip_rcv.
| 假设调用的为IP协议。
|
| IP_rcv处理函数|
|
|用到inet_protos散列表进行匹配,找到inet_proto结构。
| 假设调用的为TCP协议
|tcp_rcv 处理函数 |
| 完成从网络层到传输层的传递。
|tcp协议使用的sock结构都在tcp_prot全局变量对应的ptoto结构之sock_array[]数组中。
|采用本地端口号为索引在tcp_prot对应的数组中找到sock结构队列 |
进而找到sock结构
| 将数据报挂在到sock结果缓冲队列中 (receive_queue)|
|
| 用户读取数据,首先根据文件描述符得到inode,然后得到socket结构,进而得到sock结构, | 最后到达receive_queue队列。
|
|
|将数据包拷贝到用户缓冲区中|
举例: static struct inet_protocol tcp_protol =
{
tcp_rcv,// 处理函数。
NULL,// 初始化没有报文分段处理函数。
tcp_err, //错误控制
NULL,//
IPPROTO_TCP, //协议号
0, //copy
NULL, //数据
"TCP" // 名字
};
其中 inet_protocol 数据结构
struct inet_protocol {
int (*handler ) (struct sk_buff *skb, struct device *dev, struct opions
*opt, unsigned long daddr, unsigned short len, unsigned long saddr, int
redo, struct inet_protocol *protocol);
int (*frag_handler)(......);//参数一样
void (*err_hander)(int err, unsigned char *buff, unsigned long daddr, unsigned long saddr, struct inet_protocol *protocol);
struct inet_protocol *next;
unsigned char protocol;
unsigned char copy :1;
void *data;
char *name;
};
阅读(1431) | 评论(0) | 转发(0) |