文章10:Nginx源码分析----Nginx如何获得数据包(未完成)
2012-09-23 22:35
423 查看
文章有问题 请大家去阅读 http://tengine.taobao.org/book/index.html 中的内容
欢迎大家转载,转载请注明出处/article/1653054.html
来自yankai0219
0.序
刚看到这个问题“Nginx如何获得数据包”时,我一下子就不知所措,根本就不知道如何获取,之前就知道socket、bind、listen就建立连接,获取数据了。
本次序言,主要讲述了我是如何思考,如何找到解决问题的切入点,以供大家参考。有些不正确的地方,请指正。
Nginx作为应用层程序,如何获得来自网络的数据呢?
这部分内容,对于一个Linux网络编程的菜鸟来讲,实在难以理解,刚接触这个问题时,无从下手。
思路1来源:http://java-mzd.iteye.com/blog/1007577 提到的“怎么理解协议与程序”
即:协议就是一组规范,规定了如何保存数据。到底如何去做,那协议就不知道了。
那么到底如何去做呢?那就要交给程序来做。程序就是根据协议这一规定来编写的实际执行的代码。
那接下来就是关于程序。对于程序来讲,我们经常会定义一些数据结构来保存数据。如果从这一角度思考的话,对于Nginx这一应用层程序来讲,其获得传输层的数据也必定是通过某一个特定的数据结构来获得。
思路2来源:从TCP/IP的四层结构考虑
众所周知,TCP/IP有四层结构(也有人说5层):数据链路层---网络层---传输层----应用层。Nginx作为应用层程序,那么它只需要从传输层获得数据。可传输层又如何获得数据呢?
举例来说,在网络设备中传输的数据帧,当我请求www.baidu.com时,百度的服务器是如何从网络设备中获得我的数据的呢?肯定是从数据链路层--网络层--传输层---应用层逐层获得数据。
这儿能够找到一个点,就是数据链路层如何从网络设备中获得数据呢?以此为出发点,去网上搜索文章,果然,找到了整个问题“应用层程序如何获得数据包”的切入点。
1.正文
问题1:如何从网络设备中获得数据?专业点的话,Linux网络协议栈中数据包的处理过程
问题2:应用层如何从传输层获得数据
解决方法:
首先:阅读以下几篇文章。
问题1需要阅读文章1:Linux网络协议栈之数据包处理过程 文章2:深度探索套接字缓冲区
sk_buff skb 文章3:深度探索套接字缓冲区 这些文章都有些重复内容,建议仔细阅读文章1.
问题2需要阅读以下文章Linux内核--网络栈实现分析(六)--应用层获取数据包(上)。
再次:自己做出一个总结。我的总结如下:
1.套接字缓冲区skb
packet:通过网卡收发的报文,包括链路层、网络层、传输层的协议头和携带的数据。
Data buffer:存储packet的内存空间。
struct sk_buff结构体是linux TCP/IP网络栈中,用于管理Data buffer的结构。
套接字缓冲区skb是用结构体struct sk_buff表示,它用于在网络系统的各层之间传递数据,处于一个核心地位,该结构体包含了一组成员数据用于承载网络数据,同时,也定义了这些数据上操作的一些函数。
通俗的来讲,从以太网帧中传上来的数据都会被解析保存到struct sk_buff结构体中,该结构体中包含了所有的数据,它用于在数据链路层、网络层、传输层中传递数据,即数据链路层、网络层、传输层所获得数据都是从struct sk_buff结构体中获得。
2.数据的拷贝
为了提高网络处理的性能,应尽量减少数据包的拷贝,目前linux协议在接收数据的时候,仅仅需要拷贝两次:
1)数据包进入网卡驱动后拷贝一次
2)从内核空间递交给用户空间的应用时再拷贝一次
3.详细讲述两次数据拷贝的过程
1)数据包进入网卡驱动后拷贝一次。
由于我刚刚接触,所以不能够从源码上给出解释,只能从大致的函数调用上给出解释,以后有机会再进行补充。
当以太网帧到达网卡时,网卡驱动程序会分配一个struct sk_buffer的结构体skb,包含以太网帧所有数据信息,这儿有一次数据复制。会将数据包缓存结构struct sk_buff挂载到接收队列sk->receive_queue的队尾
2)从内核空间递交给用户空间的应用时再拷贝一次
总结,在一系列的调用中,会通过skb_copy_datagram数据进入结构体struct msghdr中。这儿会将数据拷贝到用户空间。具体的函数调用参考文章《Linux内核--网络栈实现分析(六)--应用层获取数据包(上)》。
2.依旧存在问题
截止到2012年9月23日,对于Nginx如何获取数据包依旧存在以下问题
问题:虽然知道了应用程序获取数据包的大致流程(以太网帧----struct sk_buff -----struct msghdr),但是Nginx是否采用如此方式,以及如何使用数据都是未知。
欢迎大家转载,转载请注明出处/article/1653054.html
来自yankai0219
0.序 1.正文 问题1:如何从网络设备中获得数据?专业点的话,Linux网络协议栈中数据包的处理过程 问题2:应用层如何从传输层获得数据 解决方法: 首先:阅读以下几篇文章。 再次:自己做出一个总结。我的总结如下: 1.套接字缓冲区skb 2.数据的拷贝 3.详细讲述两次数据拷贝的过程 2.依旧存在问题 |
刚看到这个问题“Nginx如何获得数据包”时,我一下子就不知所措,根本就不知道如何获取,之前就知道socket、bind、listen就建立连接,获取数据了。
本次序言,主要讲述了我是如何思考,如何找到解决问题的切入点,以供大家参考。有些不正确的地方,请指正。
Nginx作为应用层程序,如何获得来自网络的数据呢?
这部分内容,对于一个Linux网络编程的菜鸟来讲,实在难以理解,刚接触这个问题时,无从下手。
思路1来源:http://java-mzd.iteye.com/blog/1007577 提到的“怎么理解协议与程序”
如同我们自定义的应用层协议一样: 协议只是给出了一组规范,规定我们应该怎么样(按什么规则)保存数据。 在计算机间传输的永远都是二进制字节码(对于传输层,可以理解为传输的始终是下层的IP数据包),是计算机中的程序通过对这些字节码进行逻辑分析、判断,来控制程序完成差错控制等功能。 至于解析这些字节码的程序,则可以有不同的实现,只要我们按照规则来解析,并作出相应的控制,我们大可以自己写个程序是实现相应功能。 |
那么到底如何去做呢?那就要交给程序来做。程序就是根据协议这一规定来编写的实际执行的代码。
那接下来就是关于程序。对于程序来讲,我们经常会定义一些数据结构来保存数据。如果从这一角度思考的话,对于Nginx这一应用层程序来讲,其获得传输层的数据也必定是通过某一个特定的数据结构来获得。
思路2来源:从TCP/IP的四层结构考虑
众所周知,TCP/IP有四层结构(也有人说5层):数据链路层---网络层---传输层----应用层。Nginx作为应用层程序,那么它只需要从传输层获得数据。可传输层又如何获得数据呢?
举例来说,在网络设备中传输的数据帧,当我请求www.baidu.com时,百度的服务器是如何从网络设备中获得我的数据的呢?肯定是从数据链路层--网络层--传输层---应用层逐层获得数据。
这儿能够找到一个点,就是数据链路层如何从网络设备中获得数据呢?以此为出发点,去网上搜索文章,果然,找到了整个问题“应用层程序如何获得数据包”的切入点。
1.正文
问题1:如何从网络设备中获得数据?专业点的话,Linux网络协议栈中数据包的处理过程
问题2:应用层如何从传输层获得数据
解决方法:
首先:阅读以下几篇文章。
问题1需要阅读文章1:Linux网络协议栈之数据包处理过程 文章2:深度探索套接字缓冲区
sk_buff skb 文章3:深度探索套接字缓冲区 这些文章都有些重复内容,建议仔细阅读文章1.
问题2需要阅读以下文章Linux内核--网络栈实现分析(六)--应用层获取数据包(上)。
再次:自己做出一个总结。我的总结如下:
1.套接字缓冲区skb
packet:通过网卡收发的报文,包括链路层、网络层、传输层的协议头和携带的数据。
Data buffer:存储packet的内存空间。
struct sk_buff结构体是linux TCP/IP网络栈中,用于管理Data buffer的结构。
套接字缓冲区skb是用结构体struct sk_buff表示,它用于在网络系统的各层之间传递数据,处于一个核心地位,该结构体包含了一组成员数据用于承载网络数据,同时,也定义了这些数据上操作的一些函数。
通俗的来讲,从以太网帧中传上来的数据都会被解析保存到struct sk_buff结构体中,该结构体中包含了所有的数据,它用于在数据链路层、网络层、传输层中传递数据,即数据链路层、网络层、传输层所获得数据都是从struct sk_buff结构体中获得。
2.数据的拷贝
为了提高网络处理的性能,应尽量减少数据包的拷贝,目前linux协议在接收数据的时候,仅仅需要拷贝两次:
1)数据包进入网卡驱动后拷贝一次
2)从内核空间递交给用户空间的应用时再拷贝一次
3.详细讲述两次数据拷贝的过程
1)数据包进入网卡驱动后拷贝一次。
由于我刚刚接触,所以不能够从源码上给出解释,只能从大致的函数调用上给出解释,以后有机会再进行补充。
当以太网帧到达网卡时,网卡驱动程序会分配一个struct sk_buffer的结构体skb,包含以太网帧所有数据信息,这儿有一次数据复制。会将数据包缓存结构struct sk_buff挂载到接收队列sk->receive_queue的队尾
2)从内核空间递交给用户空间的应用时再拷贝一次
总结,在一系列的调用中,会通过skb_copy_datagram数据进入结构体struct msghdr中。这儿会将数据拷贝到用户空间。具体的函数调用参考文章《Linux内核--网络栈实现分析(六)--应用层获取数据包(上)》。
2.依旧存在问题
截止到2012年9月23日,对于Nginx如何获取数据包依旧存在以下问题
问题:虽然知道了应用程序获取数据包的大致流程(以太网帧----struct sk_buff -----struct msghdr),但是Nginx是否采用如此方式,以及如何使用数据都是未知。
相关文章推荐
- nginx源码分析(10)-启动过程分析
- java集合的底层如何实现的,源码分析(未完成)
- nginx源码分析—如何发送信号
- 文章1:Nginx源码分析—main函数
- nginx源码分析(10)-启动过程分析
- 文章2:Nginx源码分析-ngx_array_t动态数组
- 文章3:Nginx源码分析-ngx_list_t单链表
- 文章16:Nginx变量的源码分析
- 文章5:Nginx源码分析--事件循环
- 文章5:Nginx源码分析--事件循环
- Solr4.8.0源码分析(10)之Lucene的索引文件(3)
- Nginx源码分析-事件循环
- jQuery源码分析-10事件处理-Event-DOM-ready
- Heritrix源码分析(五) 如何让Heritrix在Ecplise等IDE下编程启动
- 网站分析获得成功的10/90法则
- nginx源码分析—队列结构ngx_queue_t
- 如何高效地分析Android_log中的问题?——查看Android源码
- Linux内核(3) - 分析内核源码如何入手(下)
- nginx源码分析(19)-方法(3)
- nginx源码分析之事件机制