美文网首页
redis网络接口封装

redis网络接口封装

作者: 剑雪封侯之 | 来源:发表于2018-12-18 09:29 被阅读0次

    网络相关的位于文件anet.c/anet.h文件中。

    接口定义

    //tcp连接
    int anetTcpConnect(char *err, char *addr, int port);
    //设置非阻塞
    int anetTcpNonBlockConnect(char *err, char *addr, int port);
    //unix本地套接字连接
    int anetUnixConnect(char *err, char *path);
    //非阻塞
    int anetUnixNonBlockConnect(char *err, char *path);
    //读
    int anetRead(int fd, char *buf, int count);
    //地址转换
    int anetResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len);
    int anetResolveIP(char *err, char *host, char *ipbuf, size_t ipbuf_len);
    //tcp server
    int anetTcpServer(char *err, int port, char *bindaddr, int backlog);
    int anetTcp6Server(char *err, int port, char *bindaddr, int backlog);
    //本地套接字server
    int anetUnixServer(char *err, char *path, mode_t perm, int backlog);
    //tcp等待连接
    int anetTcpAccept(char *err, int serversock, char *ip, size_t ip_len, int *port);
    //本地套接字等待连接
    int anetUnixAccept(char *err, int serversock);
    //写
    int anetWrite(int fd, char *buf, int count);
    //设置非阻塞
    int anetNonBlock(char *err, int fd);
    //关闭tcp的delay发送策略
    int anetEnableTcpNoDelay(char *err, int fd);
    //开启delay发送策略
    int anetDisableTcpNoDelay(char *err, int fd);
    //开启保活
    int anetTcpKeepAlive(char *err, int fd);
    //获取对端的ip:port
    int anetPeerToString(int fd, char *ip, size_t ip_len, int *port);
    //设置保活
    int anetKeepAlive(char *err, int fd, int interval);
    //获取本端的ip:port
    int anetSockName(int fd, char *ip, size_t ip_len, int *port);
    

    保活机制

    int anetKeepAlive(char *err, int fd, int interval)
    {
        int val = 1;
        //激活keepalive功能
        if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1)
        {
            anetSetError(err, "setsockopt SO_KEEPALIVE: %s", strerror(errno));
            return ANET_ERR;
        }
    
    #ifdef __linux__
        /* Default settings are more or less garbage, with the keepalive time
         * set to 7200 by default on Linux. Modify settings to make the feature
         * actually useful. */
    
        /* Send first probe after interval. */
        val = interval;
        //在interval 秒没有数据后,发送keepalive
        if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) {
            anetSetError(err, "setsockopt TCP_KEEPIDLE: %s\n", strerror(errno));
            return ANET_ERR;
        }
    
        /* Send next probes after the specified interval. Note that we set the
         * delay as interval / 3, as we send three probes before detecting
         * an error (see the next setsockopt call). */
        val = interval/3;
        if (val == 0) val = 1;
        //发送keepalive的间隔为interval/3
        if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) {
            anetSetError(err, "setsockopt TCP_KEEPINTVL: %s\n", strerror(errno));
            return ANET_ERR;
        }
    
        /* Consider the socket in error state after three we send three ACK
         * probes without getting a reply. */
        val = 3;
        //若第一次发送后收到响应,则后面val -1 次忽略,不需发送
        if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) {
            anetSetError(err, "setsockopt TCP_KEEPCNT: %s\n", strerror(errno));
            return ANET_ERR;
        }
    #else
        ((void) interval); /* Avoid unused var warning for non Linux systems. */
    #endif
    
        return ANET_OK;
    }
    

    相关文章

      网友评论

          本文标题:redis网络接口封装

          本文链接:https://www.haomeiwen.com/subject/ihhkkqtx.html