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已经建立好连接了)
整个流程就完毕了。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号