zoukankan      html  css  js  c++  java
  • 信号板拼包:数组方式(bug长度只是截短,并未清空,若之后拷贝数据长度小于之前数据长度,老数据会接在后面)

    class SignalobardMsgReadHandler : public SessionVectChar::ReadHandler
    {
    public:
      SignalobardMsgReadHandler() = delete;

      SignalobardMsgReadHandler(SignalobardMsgReadHandler _in v) = delete;

      SignalobardMsgReadHandler(sNetPack * _in data_ptr, size_t _in package_size = sizeof(sNetPack) )
        : last_time_(bzrobot::Now())
        , data_ptr_(data_ptr)
        , package_size_one_(package_size)
        , package_check_sum_(0)
        , cache_buffer_size_(0)
        , cache_buffer_()
      {
      }

      virtual ~SignalobardMsgReadHandler()
      {
      }

      inline int GetPackHeadFirstIndex( char buffer[], int one_package_size, unsigned char package_head_value )
      {
          int continue_equal_times = 0;
          for ( int i = 0; i < one_package_size; ++i )
          {
              if ( (unsigned char)buffer[i] == package_head_value )
              {
                  ++continue_equal_times;
                  if ( continue_equal_times == PackageHeadByte_ )
                  {
                      return (i-(PackageHeadByte_-1));
                  }
              }
              else
              {
                  continue_equal_times = 0;
              }
          }
          return -1;
      }

      unsigned short CalculateCheckSum ( char buffer_[], int package_size )
      {
          unsigned short check_sum = 0;
          for ( int i = 0; i < package_size-2; ++i )
          {
              check_sum += (unsigned char)buffer_[i];
          }
          return check_sum;
      }

      bzrobot::Duration _rt BlankTime() const
      {
        return bzrobot::Now() - last_time_;
      }

    protected:
      bzrobot::Result _rt RunMain(typename SessionVectChar::ReadHandler::OutputType _ut output,
                                  typename SessionVectChar::ReadHandler::InputType _in input,
                                  typename SessionVectChar::ReadHandler::OptionType _in option) final
      {
        last_time_ = bzrobot::Now();
        if(!data_ptr_)
        {
          return BZROBOT_SIGNAL_BOARD_MSG_ERROR;
        }
        TO_2_BYTE WORDtemp;

        const std::vector<char>& input_data = input;
        //存包,然后根据包长决定是否取包,多包时取用最新包
        memcpy ( &cache_buffer_[cache_buffer_size_], input_data.data(), input_data.size() );
        cache_buffer_size_ = cache_buffer_size_ + input_data.size();
        //只要缓存长度大于单个包长度,即循环进行取包,以防缓存数据堆积
        while ( cache_buffer_size_ >= package_size_one_ )
        {
            //获取数据包头在缓存中的位置
            int pack_head_index = GetPackHeadFirstIndex ( cache_buffer_, package_size_one_, PackageHeadValue_ );
            //未找到包头,丢弃该部分,返回等待新的接收数据
            if ( pack_head_index == -1 )
            {
                BZROBOT_WARNNING("SiganlBoardMsg: Not find pack head index");
                cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
                return BZROBOT_SIGNAL_BOARD_MSG_ERROR;
            }
            //找到包头,且缓存长度足够取包
            if ( pack_head_index + package_size_one_ <= cache_buffer_size_ )
            {
                memcpy( WORDtemp.b, &cache_buffer_[pack_head_index + package_size_one_ - 2], 2 );
                //确认包校验和是否相等:相等取出数据,将取出的包段及其之前的部分丢弃
                if ( CalculateCheckSum( cache_buffer_, package_size_one_ ) == WORDtemp.data16 )
                {
                    memcpy(data_ptr_, &cache_buffer_[pack_head_index], package_size_one_);
                    cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
                }
                //确认包校验和是否相等:不相等取出数据,将该包段及其之前的部分丢弃
                else
                {
                    BZROBOT_WARNNING("SiganlBoardMsg: Check sum not equal");
                    cache_buffer_size_ = cache_buffer_size_ - ( pack_head_index + package_size_one_ );
                }
            }
            //找到包头,但缓存长度不够取包,丢弃包头之前的部分
            else
            {
                BZROBOT_WARNNING("SiganlBoardMsg: Not whole package");
                cache_buffer_size_ = cache_buffer_size_ - pack_head_index;
            }
        }
        return BZROBOT_SIGNAL_BOARD_MSG_SUCCEED;
      }

      sNetPack * data_ptr_;
      size_t              package_size_one_;
      size_t              cache_buffer_size_;
      const unsigned char PackageHeadValue_ = 0xA5;
      const int           PackageHeadByte_ = 4;
      const static int    CacheBufferMaxSize_ = 1024;
      char                cache_buffer_[CacheBufferMaxSize_];
      unsigned short      package_check_sum_;
      bzrobot::Time       last_time_;
    };

  • 相关阅读:
    WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]
    事件(Event),绝大多数内存泄漏(Memory Leak)的元凶[上篇]
    谈谈关于MVP模式中VP交互问题
    如何通过VPC在本机搭建局域网
    谈谈分布式事务之三: System.Transactions事务详解[下篇]
    WCF版的PetShop之二:模块中的层次划分[提供源代码下载]
    实践重于理论——创建一个监控程序探测WCF的并发处理机制
    WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[WS标准篇]
    WCF技术剖析之三十一: WCF事务编程[中篇]
    微软将结束对Windows 2000、XP和Vista部份版本的技术支持
  • 原文地址:https://www.cnblogs.com/cj2014/p/6118372.html
Copyright © 2011-2022 走看看