文章10:Nginx源码分析----Nginx如何获得数据包(未完成)

文章有问题  请大家去阅读  http://tengine.taobao.org/book/index.html 中的内容

欢迎大家转载,转载请注明出处 http://blog.csdn.net/yankai0219/article/details/8011042
来自yankai0219

0.序
1.正文
     问题1:如何从网络设备中获得数据?专业点的话,Linux网络协议栈中数据包的处理过程
     问题2:应用层如何从传输层获得数据
  解决方法: 
          首先:阅读以下几篇文章。
   再次:自己做出一个总结。我的总结如下:
               1.套接字缓冲区skb
               2.数据的拷贝
               3.详细讲述两次数据拷贝的过程
2.依旧存在问题

0.序
        刚看到这个问题“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是否采用如此方式,以及如何使用数据都是未知。
                   
                 
                  
          
               
               

               
               

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值