Redis源码分析(二十二)--- networking网络协议传输(二)

2015-01-27 14:07:48 · 作者: · 浏览: 129
ient *c) /* 处理redis Client的内链的buffer,就是c->querybuf */ static void setProtocolError(redisClient *c, int pos) int processMultibulkBuffer(redisClient *c) /* 处理大块的buffer */ void processInputBuffer(redisClient *c) /* 处理redisClient的查询buffer */ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) /* 从Client获取查询query语句 */ void getClientsMaxBuffers(unsigned long *longest_output_list, unsigned long *biggest_input_buffer) /* 获取Client中输入buffer和输出buffer的最大长度值 */ void formatPeerId(char *peerid, size_t peerid_len, char *ip, int port) /* 格式化ip,port端口号的输出,ip:port */ int genClientPeerId(redisClient *client, char *peerid, size_t peerid_len) /* 获取Client客户端的ip,port地址信息 */ char *getClientPeerId(redisClient *c) /* 获取c->peerid客户端的地址信息 */ sds catClientInfoString(sds s, redisClient *client) /* 格式化的输出客户端的属性信息,直接返回一个拼接好的字符串 */ sds getAllClientsInfoString(void) /* 获取所有Client客户端的属性信息,并连接成一个总的字符串并输出 */ void clientCommand(redisClient *c) /* 执行客户端的命令的作法 */ void rewriteClientCommandVector(redisClient *c, int argc, ...) /* 重写客户端的命令集合,旧的命令集合的应用计数减1,新的Command Vector的命令集合增1 */ void rewriteClientCommandArgument(redisClient *c, int i, robj *newval) /* 重写Client中的第i个参数 */ unsigned long getClientOutputBufferMemoryUsage(redisClient *c) /* 获取Client中已经用去的输出buffer的大小 */ int getClientType(redisClient *c) int getClientTypeByName(char *name) /* Client中的名字的3种类型,normal,slave,pubsub */ char *getClientTypeName(int class) int checkClientOutputBufferLimits(redisClient *c) /* 判断Clint的输出缓冲区的已经占用大小是否超过软限制或是硬限制 */ void asyncCloseClientOnOutputBufferLimitReached(redisClient *c) /* 异步的关闭Client,如果缓冲区中的软限制或是硬限制已经到达的时候,缓冲区超出限制的结果会导致释放不安全, */我们从最简单的_addReplyToBuffer在缓冲区中添加回复数据开始说起,因为后面的各种addReply的方法都或多或少的调用了和这个歌方法。

/* -----------------------------------------------------------------------------
 * Low level functions to add more data to output buffers.
 * -------------------------------------------------------------------------- */
/* 往客户端缓冲区中添加内容 */
int _addReplyToBuffer(redisClient *c, char *s, size_t len) {
    size_t available = sizeof(c->buf)-c->bufpos;

    if (c->flags & REDIS_CLOSE_AFTER_REPLY) return REDIS_OK;

    /* If there already are entries in the reply list, we cannot
     * add anything more to the static buffer. */
     //如果当前的reply已经存在内容,则操作出错
    if (listLength(c->reply) > 0) return REDIS_ERR;

    /* Check that the buffer has enough space available for this string. */
    if (len > available) return REDIS_ERR;

    memcpy(c->buf+c->bufpos,s,len);
    c->bufpos+=len;
    return REDIS_OK;
}
最直接影响的一句话,就是memcpy(c->buf+c->bufpos,s,len);所以内容是加到c->buf中的,这也就是客户端的输出buffer,添加操作还有另外一种形式是添加对象类型:

/* robj添加到reply的列表中 */
void _addReplyObjectToList(redisClient *c, robj *o) {
    robj *tail;

    if (c->flags & REDIS_CLOSE_AFTER_REPLY) return;

    if (listLength(c->reply) == 0) {
        incrRefCount(o);
        //在回复列表汇总添加robj内容
        listAddNodeTail(c->reply,o);
        c->reply_bytes += zmalloc_size_sds(o->ptr);
    } else {
        tail = listNodeva lue(listLast(c->reply));

        /* Append to this object when possible. */
        if (tail->ptr != NULL &&
            sdslen(tail->ptr)+sdslen(o->ptr) <= REDIS_REPLY_CHUNK_BYTES)
        {
            c->reply_bytes -= zmalloc_size_sds(tail->ptr);
            tail = dupLastObjectIfNeeded(c->reply);
            tail->ptr = sdscatlen(tail->ptr,o->ptr,sdslen(o->ptr));
            c->reply_bytes += zmalloc_size_sds(tail->ptr);
        } else {
            incrRefCount(o);
            listAddNodeTail(c->reply,o);