redis源码阅读3----客户端连接过程


本章主要讨论在client连接到server时。server在ae过程中是如何处理的。

主要讨论的是接口函数。

大家可以把断点打在networking/acceptTcpHandler()下

以上函数在ae.c下如下部分调用:

if (!invert && fe->mask & mask & AE_READABLE) {                 fe->rfileProc(eventLoop,fd,fe->clientData,mask);   #此处                 fired++;                 fe = &eventLoop->events[fd]; /* Refresh in case of resize. */             }   rfileProc是在ae.h中被定义的 typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);   然后acceptTcpHandler则是在main函数中,初始化redis时注册的。 在server.c下    if (createSocketAcceptHandler(&server.ipfd, acceptTcpHandler) != C_OK) {         serverPanic("Unrecoverable error creating TCP socket accept handler.");   acceptTcpHandler()下最重要的调用是 anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport); 其中会调用 anetGenericAccept(char *err, int s, struct sockaddr *sa, socklen_t *len); 进入anetGenericAccept,你就会发现,最底层的unix调用--->accept   accept之后,返回到anetTcpAccept。然后他会把对端ip和端口单独存一下到cport和cip。   最后就是调用acceptCommonHandler------------>connCreateAcceptedSocket----->connCreateSocket------->zcalloc检查是否有足够内存给新连接用。 分配内存失败了还会调用zmalloc_oom_handler(size)   然后检查客户端最大连接数有没有超。 为什么检查是在accept之后的。这是官方给出的解释: /* Limit the number of connections we take at the same time.      *      * Admission control will happen before a client is created and connAccept()      * called, because we don't want to even start transport-level negotiation      * if rejected. */   最后就是调用createClient(connection *conn),创建连接。(叫创建连接可能不太合适,应该是初始化连接,能走到这一步,tcp已经建立好连接了)   整个流程就完毕了。