zoukankan      html  css  js  c++  java
  • recv 数据包形式 效率比拼

    recv 数据包形式 效率比拼_开心镇娱乐社区_百度空间

    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;
        }

  • 相关阅读:
    找回Android studio的帮助文档
    adb shell 命令详解
    Android 获取Activity当前view
    下载网络文件HttpURLConnection.getContentLength()大小为 0
    Android设置屏幕旋转后保存数据
    解决TextView drawableRight左侧图片大小不可控的问题
    Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
    人生苦短,我用Python(目录)
    爬虫学习目录
    Django-jet自定义菜单
  • 原文地址:https://www.cnblogs.com/lexus/p/3002861.html
Copyright © 2011-2022 走看看