Linux TCP/IP协议栈剖析【体系结构篇】
来源:互联网 发布:淘宝介入会打电话吗 编辑:程序博客网 时间:2024/05/01 16:23
最近在看linux内核代码,学习之余记点笔记。但是,目前整个linux源码文件大小是360M,相当于100个哈利波特全集-_-,看完的都是神仙了。所以我只准备粗略地看下它的TCP/IP协议栈,然后记点心得。
嗯,我研究的内核版本是目前最新的,linux-2.6.33.1,其实应该都大同小异。学习源码时,首先应该把它的整体脉络理清楚,然后再局部细看,这是最简捷的。本文也是简洁的归纳一下。
在linux下,socket都挂接到虚拟文件系统(VFS)上,所以可以把它当做文件来操作,如write()与read()都可以对它使用。
当我们调用fd = socket()操作时,传递过程从上到下如下所示:
VFS层:file
运输层:socket
网络层:sock
嗯,相信大家都知道了吧,VFS层上面就是应用层了,每本计算机网络相关书籍总是会先讲这几个层级结构。其中file, socket, sock是对应层次的一个内核结构,file涉及到虚拟文件系统,所以不予剖析了。
我们先看看socket结构的定义:
struct socket {socket_statestate;kmemcheck_bitfield_begin(type);shorttype;kmemcheck_bitfield_end(type);unsigned longflags;/* * Please keep fasync_list & wait fields in the same cache line */struct fasync_struct*fasync_list;wait_queue_head_twait;struct file*file;struct sock*sk;const struct proto_ops*ops;};
我们只关心最后3个结构成员,file就是对应上面的VFS层,sk则是下面的网络层,而ops则指向一个函数指针集合,对应于该运输层的操作,实际上它可指向3个集合:inet_stream_ops, inet_dgram_ops, inet_sockraw_ops。还记得我们创建socket时需要设定的type参数吗,SOCK_STREAM,SOCK_DGRAM,SOCK_RAW,相应的参数使套接字在初始化时让ops指向对应的函数指针集合。
下面就是这个函数指针集合的定义:
struct proto_ops {intfamily;struct module*owner;int(*release) (struct socket *sock);int(*bind) (struct socket *sock, struct sockaddr *myaddr, int sockaddr_len);int(*connect) (struct socket *sock, struct sockaddr *vaddr, int sockaddr_len, int flags);int(*accept) (struct socket *sock, struct socket *newsock, int flags);unsigned int(*poll) (struct file *file, struct socket *sock, struct poll_table_struct *wait);int(*ioctl) (struct socket *sock, unsigned int cmd, unsigned long arg);int(*listen) (struct socket *sock, int len);int(*shutdown) (struct socket *sock, int flags);int(*setsockopt)(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen);int(*getsockopt)(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen);int(*sendmsg) (struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len);int(*recvmsg) (struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len, int flags); 。。。。。。。
};
是不是都似曾相识呢,对,上面的都是套接字的常用操作。
最后,我们再看看网络层,sock结构,只列举了我觉得有用的成员,这个结构很长。
struct sock {struct sock_common__sk_common;struct sk_buff_headsk_receive_queue;struct sk_buff_headsk_write_queue;struct socket*sk_socket;void*sk_user_data;struct sk_buff*sk_send_head;void(*sk_state_change)(struct sock *sk);void(*sk_data_ready)(struct sock *sk, int bytes);void(*sk_write_space)(struct sock *sk);void(*sk_error_report)(struct sock *sk); int(*sk_backlog_rcv)(struct sock *sk, struct sk_buff *skb); void (*sk_destruct)(struct sock *sk);};
加下划线的两个函数指针,用于与更底层交互,当网卡有数据可读可写时用于回调。继续钻下去的话还会很深。最重要的是,它的头部是一个sock_common 结构。嗯,这相当于一个面向对象的设计,sock_common就类似是一个基类,通过强制转换可以转化。还要关注下sk_buff_head结构,他是socket内部使用的缓冲区,链表形式,以后我再写下它。
sock_common结构定义如下:同样只是简单列举一些重要的。
struct sock_common {union {struct hlist_nodeskc_node;struct hlist_nulls_node skc_nulls_node;};atomic_tskc_refcnt;intskc_tx_queue_mapping;unsigned shortskc_family;volatile unsigned charskc_state;unsigned charskc_reuse;intskc_bound_dev_if;struct proto*skc_prot;};
好了,大概结构就是这样的吧。。可以看到,就算是C语言,也运用了很多面向对象的思想。还有很抱歉,我本来准备画图说明的,结果还是惰性使然,就没画了。本来体系结构就是个很模糊的东西,关于数据包的接收与传送,以及他们在这体系结构间的传递,下篇再讲解。
- Linux TCP/IP协议栈剖析【体系结构篇】
- TCP/IP协议体系结构简介
- tcp/ip协议体系结构简介
- OSI模型与TCP/IP协议体系结构
- Linux TCP/IP协议
- Linux TCP/IP协议栈笔记
- Linux的TCP/IP协议栈
- Linux TCP/IP协议栈笔记
- Linux TCP/IP协议栈笔记(1)
- Linux TCP/IP协议栈笔记(2)
- Linux TCP/IP协议栈笔记(3)
- Linux TCP/IP协议栈笔记(4)
- Linux TCP/IP协议栈笔记(5)
- linux tcp ip 协议栈 优化
- Linux TCP/IP 协议栈源码分析
- Linux TCP/IP 协议栈源码分析
- Linux TCP/IP 协议栈源码分析
- Linux TCP/IP 协议栈源码分析
- 害羞
- [Ljava.lang.String; cannot be cast to java.lang.String
- Silverlight 3中的Behavior技术(三)
- ubuntu下缺失文件
- Teachmyself进度3
- Linux TCP/IP协议栈剖析【体系结构篇】
- Collection的toArray()使用上需要注意的地方
- 指针与引用的区别
- 宽带连接错误691,623,678......
- 几道笔试题的解法(四)
- 程序开发中版本管理之命名规则及格式
- Java编程思想学习笔记——并发
- struts 2获取Action带的参数
- Word2007 从第x页码开始设置页码