ngx_connection_s

来源:互联网 发布:java 数组长度 long 编辑:程序博客网 时间:2024/05/02 04:44
    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  
    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服务器使用了事件驱动机制来处理网络请求。

0 0