最近研究memcached 的iov部分,把理解的相关东西做个笔记,防止忘了,有错误之处也欢迎各位指摘。微笑 struct msghdr { void *msg_name; /* Socket name */ int msg_namelen; /* Length of name */ struct iovec *msg_iov; /* Data blocks */ int msg_iovlen; /* Number of blocks */有几个iov块 void *msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */ int msg_accrightslen; /* Length of rights list */ }; telnet localhost 11211后 set key 0 0 4 key1 get key ...分析1 VALUE key 0 4 key1 分析1: gdb(如何用gdb见http://blog.csdn.net/yxnyxnyxnyxnyxn/article/details/7955259)跟踪: 3995 switch (transmit(c)) { (gdb) s transmit (fd=<value optimized out>, which=<value optimized out>, arg=0x7fffe8013560) at memcached.c:3691 3691 if (c->msgcurr < c->msgused && (gdb) n 3692 c->msglist[c->msgcurr].msg_iovlen == 0) { (gdb) 3691 if (c->msgcurr < c->msgused && (gdb) 3698 struct msghdr *m = &c->msglist[c->msgcurr]; (gdb) 3700 res = sendmsg(c->sfd, m, 0); (gdb) 3701 if (res > 0) { (gdb) p res $20 = <value optimized out> (gdb) n 3700 res = sendmsg(c->sfd, m, 0); (gdb) p res $21 = <value optimized out> (gdb) n 3701 if (res > 0) { (gdb) p res $22 = 26 (gdb) l 3696 if (c->msgcurr < c->msgused) { 3697 ssize_t res; 3698 struct msghdr *m = &c->msglist[c->msgcurr]; 3699 3700 res = sendmsg(c->sfd, m, 0); 3701 if (res > 0) { 3702 pthread_mutex_lock(&c->thread->stats.mutex); 3703 c->thread->stats.bytes_written += res; 3704 pthread_mutex_unlock(&c->thread->stats.mutex); 3705 (gdb) p c->msglist[c->msgcurr] $23 = {msg_name = 0x7fffe80136d8, msg_namelen = 16, msg_iov = 0x7fffe8014e80, msg_iovlen = 4, msg_control = 0x0, msg_controllen = 0, msg_flags = 0} (gdb) p c->msglist[c->msgcurr].msg_iov msg_iov msg_iovlen (gdb) p c->msglist[c->msgcurr].msg_iov $24 = (struct iovec *) 0x7fffe8014e80 (gdb) p c->msglist[c->msgcurr].msg_iov.buf 没有名为 buf 的成员 (gdb) p c->msglist[c->msgcurr].msg_iov[0].iov_base $25 = (void *) 0x412097 (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[0].iov_base $26 = 0x412097 "VALUE " (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[1].iov_base $27 = 0x7ffff7e2b048 "key" (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[2].iov_base $28 = 0x7ffff7e2b04c " 0 4\r\nkey1\r\n" (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[3].iov_base $29 = 0x411944 "END\r\n" (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[4].iov_base $30 = 0x0 msg_iovlen = 4 //(3+1) if (add_iov(c, “VALUE “, 6) || add_iov(c, ITEM_key(it), it->nkey) || add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes)) 用了3个iov结构体, add_iov() { c->msgbytes += len; c->iovused++; m->msg_iovlen++; } 调用完了之后执行下面的语句:add_iov(c, "END\r\n", 5) add_iov() { c->msgbytes += len; c->iovused++; m->msg_iovlen++;// 加到了4} res:26 发送成功的字节数VALUE key 0 4 key1\r\nEND\r\n set key 0 0 4 key1 set key1 0 0 4 key2 get key key2 VALUE key 0 4 key1 VALUE key2 0 4 key2 (gdb) p c->msglist[c->msgcurr] $52 = {msg_name = 0x7fffe80136d8, msg_namelen = 16, msg_iov = 0x7fffe8014e80, msg_iovlen = 7, msg_control = 0x0, msg_controllen = 0, msg_flags = 0} (gdb) n 3708 while (m->msg_iovlen > 0 && res >= m->msg_iov->iov_len) { (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[0].iov_base $53 = 0x412097 "VALUE " (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[1].iov_base $54 = 0x7ffff7e2b048 "key" (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[2].iov_base $55 = 0x7ffff7e2b04c " 0 4\r\nkey1\r\n" (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[3].iov_base $56 = 0x412097 "VALUE " (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[4].iov_base $57 = 0x7ffff7e2b0a8 "key2" (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[5].iov_base $58 = 0x7ffff7e2b0ad " 0 4\r\nkey2\r\n" (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[6].iov_base $59 = 0x411944 "END\r\n" (gdb) p (char *)c->msglist[c->msgcurr].msg_iov[7].iov_base $60 = 0x0