11.7 ngx_connection_s结构体

时间 : 16-03-29 栏目 : nginx专题 作者 : 老薛 评论 : 0 点击 : 838 次

该结构体用于描述一个网络连接。我们已经知道,Nginx服务器使用事件驱动模型来处理网络连接请求。每当Nginx服务器产生一个新的socket时,就会构造一个ngx_connection_s结构体,将该socket的属性和数据信息保存下来。该结构体的完整定义在/nginx/src/core/ngx_connection.h文件中可以找到,其中包含的成员较多,我们仅对其中重要的成员进行介绍。
 

    struct ngx_connection_s {  
        void                    *data;  
        ngx_event_t             *read;  
        ngx_event_t             *write;  

*data,用来关联其他的ngx_connection_s结构体。

*read,设置该连接的读事件。

*write,设置该连接的写事件。

    ngx_socket_t            fd;  
        ngx_recv_pt             recv;  
        ngx_send_pt             send;  
        ngx_recv_chain_pt       recv_chain;  
        ngx_send_chain_pt       send_chain;  
        ngx_listening_t         *listening;  
        off_t                   sent;  
        ngx_log_t               *log;  
        ngx_pool_t              *pool;  
        struct sockaddr         *sockaddr;  
        socklen_t               socklen;  
        ngx_str_t               addr_text;  
        struct sockaddr         *local_sockaddr;  
    …  
    }  

前面这几个参数与事件驱动模型有关。这里的参数用于设置网络连接相关的属性,重点需要理解下面几个参数:

fd,用于设置连接socket的socket描述字。

recv和recv_chain,指向完成(批量)数据接收函数的函数指针。

send和recv_chain,指向完成(批量)数据发送函数的函数指针。

这四个函数指针的定义在不同的系统平台中是有差异的。我们来讨论一下Nginx程序是如何处理这种差异的。

这四个函数指针在Unix/Linux平台上的定义我们可以在/nginx/os/unix/ngx_os.h文件中找到:
 

    typedef ssize_t (*ngx_recv_pt)(ngx_connection_t *c, u_char *buf, size_t size);  
    typedef ssize_t (*ngx_recv_chain_pt)(ngx_connection_t *c, ngx_chain_t *in);  
    typedef ssize_t (*ngx_send_pt)(ngx_connection_t *c, u_char *buf, size_t size);  
    typedef ngx_chain_t *(*ngx_send_chain_pt)(ngx_connection_t *c, ngx_chain_t *in, off_t limit);  

可以看到,成员recv和send与成员recv_chain和recv_chain指向的函数主要区别在于它们处理的数据类型有所不同。在程序中这四个成员的赋值是在/nginx/event/ngx_event.h文件中的宏定义:

    #define ngx_recv                ngx_io.recv  
    #define ngx_recv_chain          ngx_io.recv_chain  
    #define ngx_udp_recv            ngx_io.udp_recv  
    #define ngx_send                ngx_io.send  
    #define ngx_send_chain          ngx_io.send_chain  

而其中ngx_io的类型为ngx_os_io_t结构体,其定义也在/nginx/os/unix/ngx_os文件中:
 

    typedef struct {  
        ngx_recv_pt         recv;  
        ngx_recv_chain_pt   recv_chain;  
        ngx_recv_pt         udp_recv;  
        ngx_send_pt         send;  
        ngx_send_chain_pt   send_chain;  
        ngx_uint_t          flags;  
    } ngx_os_io_t;  

从上面宏定义和ngx_os_io_t结构体定义的文件以及定义内容来看,大家应该可以猜测到,ngx_io实际上是Nginx程序中统一的IO结构,而ngx_os_io_t则是针对不同系统平台分别定制的特定的IO结构。分析到这里,大家是不是觉得很有一点面向对象的感觉呢?Nginx程序确实是通过这样的方式来处理因平台系统不同造成的网络IO差异的。

我们回到ngx_connection_s结构体,继续学习其他成员。

*listening,用于设置该网路连接的socket监听,它对应一个ngx_listening_s结构体,而该ngx_listening_s结构体中的*connection成员又将指向该ngx_connection_s结构体。

*sent用于设置该连接已发送或者已接收数据的数量。

*log用于存放Nginx服务器的日志配置。

*pool指向Nginx程序建立的内存池的首地址。

这四个参数用于设置接收到的对端socket的地址属性和本地监听socket的地址属性。

*sockaddr指向保存对端监听socket的地址结构。

socklen记录对端socket的信息长度。

addr_text存放socket地址。

*local_sockaddr指向保存本地监听socket的地址结构。该信息来自ngx_listening_t结构体,最初来源于配置文件。

以上介绍的成员是该结构体中的主要成员,在本书后面的学习中会多次遇到。该结构体与ngx_event_s结构体是紧密相关的,许多成员的赋值都来自于ngx_event_s结构体中对应的成员。究其原因,就是Nginx服务器使用了事件驱动机制来处理网络请求。

本文标签

除非注明,文章均为( 老薛 )原创,转载请保留链接: http://www.bdkyr.com/nginx-2/1567.html

11.7 ngx_connection_s结构体:等您坐沙发呢!

发表评论

4 + 2 = ?


博主微信号,很高兴为您提供帮助

随便看看

0