redis基础组件-anet简介

特点

  • 模块非常简洁,提供了监听指定端口,链接指定地址,读,写网络句柄等功能

重要的接口函数

  • 监听指定端口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    int anetTcpServer(char *err, int port, char *bindaddr)
    {
    int s, on = 1;
    struct sockaddr_in sa;

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    anetSetError(err, "socket: %s\n", strerror(errno));
    return ANET_ERR;
    }
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
    anetSetError(err, "setsockopt SO_REUSEADDR: %s\n", strerror(errno));
    close(s);
    return ANET_ERR;
    }
    memset(&sa,0,sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    sa.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bindaddr) {
    if (inet_aton(bindaddr, &sa.sin_addr) == 0) {
    anetSetError(err, "Invalid bind address\n");
    close(s);
    return ANET_ERR;
    }
    }
    if (bind(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
    anetSetError(err, "bind: %s\n", strerror(errno));
    close(s);
    return ANET_ERR;
    }
    if (listen(s, 511) == -1) { /* the magic 511 constant is from nginx */
    anetSetError(err, "listen: %s\n", strerror(errno));
    close(s);
    return ANET_ERR;
    }
    return s;
    }
  • 链接指定地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    static int anetTcpGenericConnect(char *err, char *addr, int port, int flags)
    {
    int s, on = 1;
    struct sockaddr_in sa;

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    anetSetError(err, "creating socket: %s\n", strerror(errno));
    return ANET_ERR;
    }
    /* Make sure connection-intensive things like the redis benckmark
    * will be able to close/open sockets a zillion of times */
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    if (inet_aton(addr, &sa.sin_addr) == 0) {
    struct hostent *he;

    he = gethostbyname(addr);
    if (he == NULL) {
    anetSetError(err, "can't resolve: %s\n", addr);
    close(s);
    return ANET_ERR;
    }
    memcpy(&sa.sin_addr, he->h_addr, sizeof(struct in_addr));
    }
    if (flags & ANET_CONNECT_NONBLOCK) {
    if (anetNonBlock(err,s) != ANET_OK)
    return ANET_ERR;
    }
    if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
    if (errno == EINPROGRESS &&
    flags & ANET_CONNECT_NONBLOCK)
    return s;

    anetSetError(err, "connect: %s\n", strerror(errno));
    close(s);
    return ANET_ERR;
    }
    return s;
    }
  • 读写指定句柄

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /* Like read(2) but make sure 'count' is read before to return
    * (unless error or EOF condition is encountered) */
    int anetRead(int fd, char *buf, int count)
    {
    int nread, totlen = 0;
    while(totlen != count) {
    nread = read(fd,buf,count-totlen);
    if (nread == 0) return totlen;
    if (nread == -1) return -1;
    totlen += nread;
    buf += nread;
    }
    return totlen;
    }

    /* Like write(2) but make sure 'count' is read before to return
    * (unless error is encountered) */
    int anetWrite(int fd, char *buf, int count)
    {
    int nwritten, totlen = 0;
    while(totlen != count) {
    nwritten = write(fd,buf,count-totlen);
    if (nwritten == 0) return totlen;
    if (nwritten == -1) return -1;
    totlen += nwritten;
    buf += nwritten;
    }
    return totlen;
    }
-------------本文结束 感谢阅读-------------