recv 数据包形式 效率比拼
由于tcp是流协议,但实际中使用数据包协议比较多,所以应用层需要自己包装一个
void client_thread(tp_work*this, tp_work_desc*job) {
int connectID = (int) job->chnum;
free(job);
char left_buf[MSG_RECV_LEN]="0";
int left_len = 0;
int res;
int i;
char rbuf[MSG_RECV_LEN];
while(1){
memset(rbuf,'\0',MSG_RECV_LEN);
res = recv(connectID, rbuf, MSG_RECV_LEN,0);
if (res < 0) {
close(connectID);
break ;
} else if (0 == res) {
close(connectID);
break ;
} else {
for(i = 0;i < res;i++){
if(rbuf[i] == '\0'){ //分割符
left_buf[left_len] = '\0';
msg_recv_queue_put(g_pRMsg, connectID,left_buf,left_len+1);
left_len = 0;
continue;
}
else {
left_buf[left_len] = rbuf[i];
left_len ++;
}
if(left_len == MSG_RECV_LEN){
left_len = 0;
}
}
}
}
}这个代码简介,结构清晰
void client_thread(tp_work*this, tp_work_desc*job) {
int connectID = (int) job->chnum;
free(job);
char left_buf[MSG_RECV_LEN]="0";
int left_len = 0;
int res;
char rbuf[MSG_RECV_LEN];
int pro_len;
char *pos;
char *pCur;
while(1){
res = recv(connectID, rbuf, MSG_RECV_LEN,0);
pCur = rbuf;
if (res < 0) {
close(connectID);
break ;
} else if (0 == res) {
close(connectID);
break ;
} else {
while(res > 0&&(pos = memchr(pCur,'\0',res)) != 0){//是否含有 分隔符
pro_len = pos - pCur+1;
if(left_len+pro_len <= MSG_RECV_LEN){//超过最大长度
memcpy(left_buf+left_len,pCur,pro_len);
msg_recv_queue_put(g_pRMsg, connectID,left_buf,left_len+pro_len);
}
left_len = 0;
pCur = pCur + pro_len;
res = res -pro_len;
}
if(left_len + res >= MSG_RECV_LEN){
left_len = 0;
continue;
}
memcpy(left_buf+left_len,pCur,res);
left_len += res;
}
}
}这个代码稍微有点晦涩,调用系统的string库函数查找分割符
经过测试在不优化编译的情况下第二种代码是第一种的7-10倍
由此得出string库的函数是经过优化的,速度很快,memcpy memstr 效率很高
/* Search no more than N bytes of S for C. */
//若成功则返回字符在缓冲区的位置,否则返回NULL
//原型为
//void *memchr( const void *buf, int c, size_t count )
__ptr_t //就是void*
__memchr (s, c_in, n)
const __ptr_t s; //缓冲区指针
int c_in; //要查找的字符
size_t n; //要检查的字符数
{
const unsigned char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, magic_bits, charmask;
unsigned reg_char c; //这里reg_char可以认为是char
c = (unsigned char) c_in;
/* Handle the first few characters by reading one character at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
for (char_ptr = (const unsigned char *) s;
n > 0 && ((unsigned long int) char_ptr //char的size是1,unsigned long int的size 是4
& (sizeof (longword) - 1)) != 0;//查找前几个字符,一直到可以与unsigned long int对齐的地方
--n, ++char_ptr) //这时候如果没有查找到,char_ptr的地址已经可以被4整除了
if (*char_ptr == c)
return (__ptr_t) char_ptr;
/* All these elucidatory comments refer to 4-byte longwords,
but the theory applies equally well to 8-byte longwords. */
longword_ptr = (unsigned long int *) char_ptr;
//这里开始没有看懂,请高手指点
/* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
the "holes." Note that there is a hole just to the left of
each byte, with an extra at the end:
bits: 01111110 11111110 11111110 11111111
bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
The 1-bits make sure that carries propagate to the next 0-bit.
The 0-bits provide holes for carries to fall into. */
if (sizeof (longword) != 4 && sizeof (longword) != 8)
abort ();
#if LONG_MAX <= LONG_MAX_32_BITS
magic_bits = 0x7efefeff;
#else
magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;
#endif
/* Set up a longword, each of whose bytes is C. */
charmask = c | (c << 8);
charmask |= charmask << 16;
#if LONG_MAX > LONG_MAX_32_BITS
charmask |= charmask << 32;
#endif
/* Instead of the traditional loop which tests each character,
we will test a longword at a time. The tricky part is testing
if *any of the four* bytes in the longword in question are zero. */
while (n >= sizeof (longword))
{
longword = *longword_ptr++ ^ charmask;
/* Add MAGIC_BITS to LONGWORD. */
if ((((longword + magic_bits)
/* Set those bits that were unchanged by the addition. */
^ ~longword)
/* Look at only the hole bits. If any of the hole bits
are unchanged, most likely one of the bytes was a
zero. */
& ~magic_bits) != 0)
{
/* Which of the bytes was C? If none of them were, it was
a misfire; continue the search. */
const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
if (cp[0] == c)
return (__ptr_t) cp;
if (cp[1] == c)
return (__ptr_t) &cp[1];
if (cp[2] == c)
return (__ptr_t) &cp[2];
if (cp[3] == c)
return (__ptr_t) &cp[3];
#if LONG_MAX > 2147483647
if (cp[4] == c)
return (__ptr_t) &cp[4];
if (cp[5] == c)
return (__ptr_t) &cp[5];
if (cp[6] == c)
return (__ptr_t) &cp[6];
if (cp[7] == c)
return (__ptr_t) &cp[7];
#endif
}
n -= sizeof (longword);
}
char_ptr = (const unsigned char *) longword_ptr;
while (n-- > 0)
{
if (*char_ptr == c)
return (__ptr_t) char_ptr;
else
++char_ptr;
}