anet是redis对tcp/ip网络中socket api接口的一个全面的封装,针对server/client端。封装的api的接口如下,注释了主要的接口:

// tcp连接
int anetTcpConnect(char *err, char *addr, int port);
// 非阻塞连接
int anetTcpNonBlockConnect(char *err, char *addr, int port);
// 非阻塞绑定
int anetTcpNonBlockBindConnect(char *err, char *addr, int port, char *source_addr);
// 非阻塞绑定
int anetTcpNonBlockBestEffortBindConnect(char *err, char *addr, int port, char *source_addr);
//unix socket connect
int anetUnixConnect(char *err, char *path);
// unix non-block connect
int anetUnixNonBlockConnect(char *err, char *path);
// socket读数据
int anetRead(int fd, char *buf, int count);
// 解析所有的东西
int anetResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len);
// 解析ip
int anetResolveIP(char *err, char *host, char *ipbuf, size_t ipbuf_len);
// ipv4下socket()函数创建socket
int anetTcpServer(char *err, int port, char *bindaddr, int backlog);
// ipv6下create socket
int anetTcp6Server(char *err, int port, char *bindaddr, int backlog);
// unix create socket and bind
int anetUnixServer(char *err, char *path, mode_t perm, int backlog);
// tcp socket accept()
int anetTcpAccept(char *err, int serversock, char *ip, size_t ip_len, int *port);
// unix socket accept()
int anetUnixAccept(char *err, int serversock);
// socket write data to buffer
int anetWrite(int fd, char *buf, int count);
// set socket to non-block mode
int anetNonBlock(char *err, int fd);
// set socket to block mode
int anetBlock(char *err, int fd);
// set socket mode to tcp_nodelay
int anetEnableTcpNoDelay(char *err, int fd);
// shutdown tcp_nodelay mode
int anetDisableTcpNoDelay(char *err, int fd);
// open keepalive mode
int anetTcpKeepAlive(char *err, int fd);
// set socket send timeout value
int anetSendTimeout(char *err, int fd, long long ms);
int anetPeerToString(int fd, char *ip, size_t ip_len, int *port);
int anetKeepAlive(char *err, int fd, int interval);
// get socket port and name
int anetSockName(int fd, char *ip, size_t ip_len, int *port);
int anetFormatAddr(char *fmt, size_t fmt_len, char *ip, int port);
int anetFormatPeer(int fd, char *fmt, size_t fmt_len);
int anetFormatSock(int fd, char *fmt, size_t fmt_len);

根据上面的接口名称和注释,做过网络编程的同学就能很快发现redis的anet部分只是对tcp socket api接口的一次封装。

其中有几个主要的方法根据我自己的理解进行分析:

设置tcp_nodelay的方法包装成了连个接口,分别是打开与关闭

static int anetSetTcpNoDelay(char *err, int fd, int val)
{if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) == -1){anetSetError(err, "setsockopt TCP_NODELAY: %s", strerror(errno));return ANET_ERR;}return ANET_OK;
}
int anetEnableTcpNoDelay(char *err, int fd)
{return anetSetTcpNoDelay(err, fd, 1);
}int anetDisableTcpNoDelay(char *err, int fd)
{return anetSetTcpNoDelay(err, fd, 0);
}

使用者根据自己的实际情况选择合适的调用接口。

里面有个ipv4和ipv6的考虑挺周全的,接口如下:

int anetGenericResolve(char *err, char *host, char *ipbuf, size_t ipbuf_len,int flags)
{struct addrinfo hints, *info;int rv;memset(&hints,0,sizeof(hints));if (flags & ANET_IP_ONLY) hints.ai_flags = AI_NUMERICHOST;hints.ai_family = AF_UNSPEC;hints.ai_socktype = SOCK_STREAM;  /* specify socktype to avoid dups */// hostname infoif ((rv = getaddrinfo(host, NULL, &hints, &info)) != 0) {anetSetError(err, "%s", gai_strerror(rv));return ANET_ERR;}if (info->ai_family == AF_INET) {// ipv4struct sockaddr_in *sa = (struct sockaddr_in *)info->ai_addr;inet_ntop(AF_INET, &(sa->sin_addr), ipbuf, ipbuf_len);} else {// IPv6的解法struct sockaddr_in6 *sa = (struct sockaddr_in6 *)info->ai_addr;inet_ntop(AF_INET6, &(sa->sin6_addr), ipbuf, ipbuf_len);}freeaddrinfo(info);return ANET_OK;
}

一般情况下,自己编程时只考虑到了ipv4的情况,但是未考虑ipv6的情况,现在看这些代码觉得作者还是挺细心周到的。

总体感觉这部分内容比较容易,暂时写到这里。

Redis源码分析之anet网络通信的封装相关推荐

  1. redis源码分析 -- cs结构之服务器

    服务器与客户端是如何交互的 redis客户端向服务器发送命令请求,服务器接收到客户端发送的命令请求之后,读取解析命令,并执行命令,同时将命令执行结果返回给客户端. 客户端与服务器交互的代码流程如下图所 ...

  2. Redis源码分析:基础概念介绍与启动概述

    Redis源码分析 基于Redis-5.0.4版本,进行基础的源码分析,主要就是分析一些平常使用过程中的内容.仅作为相关内容的学习记录,有关Redis源码学习阅读比较广泛的便是<Redis设计与 ...

  3. Redis源码分析(一)redis.c //redis-server.c

    Redis源码分析(一)redis.c //redis-server.c 入口函数 int main() 4450 int main(int argc, char **argv) {4451 init ...

  4. 10年大厂程序员是如何高效学习使用redis的丨redis源码分析丨redis存储原理

    10年大厂程序员是怎么学习使用redis的 1. redis存储原理分析 2. redis源码学习分享 3. redis跳表和B+树详细对比分析 视频讲解如下,点击观看: 10年大厂程序员是如何高效学 ...

  5. Redis源码分析(一)--Redis结构解析

    从今天起,本人将会展开对Redis源码的学习,Redis的代码规模比较小,非常适合学习,是一份非常不错的学习资料,数了一下大概100个文件左右的样子,用的是C语言写的.希望最终能把他啃完吧,C语言好久 ...

  6. Redis 源码分析之故障转移

    在 Redis cluster 中故障转移是个很重要的功能,下面就从故障发现到故障转移整个流程做一下详细分析. 故障检测 PFAIL 标记 集群中每个节点都会定期向其他节点发送 PING 消息,以此来 ...

  7. Redis源码分析之PSYNC同步

    Redis master-slave 同步源码分析 (1)slave 流程分析 (2)master 流程分析 Slave 分析 当Redis 启动后,会每隔 1s 调用 replicationCron ...

  8. Redis源码分析 —— 发布与订阅

    前言 通过阅读Redis源码,配合GDB和抓包等调试手段,分析Redis发布订阅的实现原理,思考相关问题. 源码版本:Redis 6.0.10 思考问题 发布订阅基本概念介绍 订阅频道 -- SUBS ...

  9. Redis源码分析之工具类util

    在redis源码中的辅助工具类中,主要包括大小端转换.SHA算法以及util.h中对应的算法. 大小端转换: LittleEndian:低位字节数据存放于低地址,高位字节数据存放于高地址. BigEn ...

最新文章

  1. 合并模拟器和真机的静态库动态库aggregate
  2. POJ 2135 Farm Tour amp;amp; HDU 2686 Matrix amp;amp; HDU 3376 Matrix Again 费用流求来回最短路...
  3. 服务端第四次课程:MVC,控制器,视图渲染
  4. python本地编译器_Python学习札记(0)——Python开发环境搭载及推荐几款Python编译器...
  5. org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyR
  6. 深入理解JavaScript系列:This? Yes,this!
  7. python数据类型--数字、字符串
  8. 使用 Win 7 必须知道的快捷键
  9. android模拟点击滑动,模拟Android的view点击和滑动监听
  10. python垃圾回收离职_垃圾回收gc.md
  11. 用iptables实现NAT
  12. oracle10g_database安装教程,Oracle Database 10g数据库安装及配置教程
  13. 安装kali 不再难
  14. 一文带你搞懂Vue中的Excel导入导出
  15. hdu 4408 Minimum Spanning Tree
  16. 当青春走到尽头你会想念你自己吗
  17. Application Cache is a Douchebag
  18. HDU 3277 Marriage Match III(并查集+二分+最大流)
  19. 遗传-粒子群算法遗传-禁忌搜索算法求解TSP问题
  20. 2022QS世界大学学科排名,中国大陆上榜课程数仅次于美英,化学、材料、生物集中度最高 | 美通社头条...

热门文章

  1. 面向对象的故事~数据底层操作告诉了我们接口,抽象类,继承与多态性的使用~续(TestBase继承ITest是多余的?)...
  2. Linux中的MAN命令
  3. Diango博客--9.归档、分类和标签页
  4. 背单词软件 单词风暴 分享id_周一考研高效背单词系列(一):利用单词软件如何背好单词...
  5. Python 面向对象之双下方法,内置函数
  6. app中 html5 search 事件,事件 - Cordova中文网
  7. scrapy框架_Python学习之Scrapy框架
  8. c语言有趣代码_为什么C语言永远不会过时?
  9. python生成requirements.txt的两种方法
  10. Flask-Script扩展命令行manager = Manager(app)