zoukankan      html  css  js  c++  java
  • nginx模块编程之获取客户ip及端口号

    ngx_request_t结构体中有一个connection定义,该定义指向一个ngx_connection_t的结构体:

    结构体定义如下:

     1 struct ngx_connection_s {
     2     void               *data;
     3     ngx_event_t        *read;
     4     ngx_event_t        *write;
     5 
     6     ngx_socket_t        fd;
     7 
     8     ngx_recv_pt         recv;
     9     ngx_send_pt         send;
    10     ngx_recv_chain_pt   recv_chain;
    11     ngx_send_chain_pt   send_chain;
    12 
    13     ngx_listening_t    *listening;
    14 
    15     off_t               sent;
    16 
    17     ngx_log_t          *log;
    18 
    19     ngx_pool_t         *pool;
    20 
    21     struct sockaddr    *sockaddr;
    22     socklen_t           socklen;
    23     ngx_str_t           addr_text;
    24 
    25     ngx_str_t           proxy_protocol_addr;
    26 
    27 #if (NGX_SSL)
    28     ngx_ssl_connection_t  *ssl;
    29 #endif
    30 
    31     struct sockaddr    *local_sockaddr;
    32     socklen_t           local_socklen;
    33 
    34     ngx_buf_t          *buffer;
    35 
    36     ngx_queue_t         queue;
    37 
    38     ngx_atomic_uint_t   number;
    39 
    40     ngx_uint_t          requests;
    41 
    42     unsigned            buffered:8;
    43 
    44     unsigned            log_error:3;     /* ngx_connection_log_error_e */
    45 
    46     unsigned            unexpected_eof:1;
    47     unsigned            timedout:1;
    48     unsigned            error:1;
    49     unsigned            destroyed:1;
    50 
    51     unsigned            idle:1;
    52     unsigned            reusable:1;
    53     unsigned            close:1;
    54 
    55     unsigned            sendfile:1;
    56     unsigned            sndlowat:1;
    57     unsigned            tcp_nodelay:2;   /* ngx_connection_tcp_nodelay_e */
    58     unsigned            tcp_nopush:2;    /* ngx_connection_tcp_nopush_e */
    59 
    60     unsigned            need_last_buf:1;
    61 
    62 #if (NGX_HAVE_IOCP)
    63     unsigned            accept_context_updated:1;
    64 #endif
    65 
    66 #if (NGX_HAVE_AIO_SENDFILE)
    67     unsigned            busy_count:2;
    68 #endif
    69 
    70 #if (NGX_THREADS)
    71     ngx_thread_task_t  *sendfile_task;
    72 #endif
    73 };

    结构体中,有两个sockaddr地址结构定义,分别是sockaddr以及local_sockaddr;前者为客户端地址,后者为服务器端地址;下面来看sockaddr的定义:

    struct sockaddr {
      unsigned short sa_family; /* address family, AF_xxx */
      char sa_data[14]; /* 14 bytes of protocol address */
      };
    说明:
    sa_family是地址家族,是“AF_xxx”的形式。常设为“AF_INET”,代表Internet(TCP/IP)地址族。
    sa_data是协议地址,由sa_family决定。如果sa_family=AF_INET,则sa_data就是sockaddr_in的 sin_addr和sin_port,用于为套接口储存目标地址和端口信息。为了解决struct sockaddr赋值以及访问,提供了了一个并列的结构struct sockadd_in(“in”代表
    “Internet”),换句话说,sockaddr的数据存储大小和结构完全和sockaddr_in一致,可以直接强制转换。
    struct sockaddr_in{ 
    short int   sin_family;  /*地址族信息,通常是AF-xxxx的形式*/ 
    unsigned short    int sin_port; /*端口信息*/ 
    struct in_addr    sin_addr;     /*网络地址*/ 
    unsigned char     sin_zero[8];  /*补位用的0,to make same size as struct sockaddr*/ 
    } 

    关于这两个结构体,他们占用的内存大小是一样的,当sockaddr_in.sin_family = AF_INET时,他们的内存布局也一样的!看看sockaddr结构体自身就知道了,它仅仅是个char数组,大小与sockaddr_in等同。

    这两个结构体使用转化的例子如下:

    • sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数
    /*sockaddr_in强制转化为sockaddr,用于传入系统调用函数*/
    int sockfd;
    struct sockaddr_in my_addr;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
    my_addr.sin_family = AF_INET; /* 主机字节序 */
    my_addr.sin_port = htons(MYPORT); /* short, 网络字节序 */
    
    my_addr.sin_addr.s_addr = inet_addr("192.168.0.1");
    
    bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */
    //memset(&my_addr.sin_zero, 0, 8);
    
    bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));//将sockaddr_in强制转化为sockaddr,用于传入系统调用函数
    • sockaddr结构强制转换成sockaddr_in结构,从而得到ip地址和端口号
    struct sockaddr_in *ip = (struct sockaddr_in *) (r->connection->sockaddr); 
    char* addr = inet_ntoa(ip->sin_addr);//地址转化函数,返回字符串指针
    unsigned short port = ntohs(ip->sin_port);//大小端转换
     
  • 相关阅读:
    设计模式的分类
    SQL Server 2005 TSQL 学习笔记:排名函数
    JS正则表达式语法
    魅族 “拜产品教”公司的优秀与局限
    jqueryMobile初始化组件
    Loading Scripts Without Blocking
    LabJs学习笔记:分析图
    翻转的css3样式
    IE(IE6/IE7/IE8)支持HTML5标签
    我的空间轨迹!
  • 原文地址:https://www.cnblogs.com/paulweihan/p/4739709.html
Copyright © 2011-2022 走看看