BinaryAnalyzer

#pragma once


#include ".\NetCommuication\commuanalyzer.h"
class CSzBinaryAnalyzer :
  public CCommuAnalyzer
{
public:
  CSzBinaryAnalyzer(void);
  ~CSzBinaryAnalyzer(void);


  
  /*
  * Desc: 
  *     依据输入的业务报文,打包成网络报文并输出
  *     默认的通讯分析器只含简单的网络层组包解包逻辑逻辑,不包含对于业务协议的包。网络包规则如下:
  *         网络包头包括:包头识别码(换行回车符:'\n\r')+ 一个整型值的长度,无包尾
  *     注:当符合以下条件的情况下可以不调用该接口
  *       1、业务报文件长度小于 TCPConnect中定义的:最大网络接收缓冲区大小
  *       2、对网络包组包规则无特殊要求
  * Pram:
  *     pszBodyIn         业务报文
  *     iBodyLenIn        业务报文长度
  *     pszNetBufOut      网络报文       【输出参数由调用者清除】
  *     iBufLenOut        网络报文长度
  * Retr:
  *     bool              打包成功返回 true, 打包失败返回 false
  */ 
  virtual bool PackNetPackage(char* pszBodyIn, int iBodyLenIn, char*& pszNetBufOut, int& iBufLenOut);
    
  /*
  * Desc: 
  *     依据输入的网络接收缓冲区,判断是否存在脏数据需要被清理,并通过返回值iSkipLen告知需要被处理的脏数据长度。
  *     必须实现存在错误包时的应对处理,由(-1:抛弃错误数据,但不断开网络;-2:中断网络)
  *     
  * Pram:
  *     pszNetRcvBufIn     网络接收缓冲区
  *     iNetRcvBufLenIn    网络接收缓冲区长度
  *     iSkipLen           网络接收缓冲区超始位置开始需要被忽略的脏数据长度, 必须正确,否则会导致清楚正确的数据
  * Retr:
  *     int                0:无脏数据  -1:有脏数据但不中断网络, -2:有脏数据需要中断网络
  */ 
  virtual int IsExistDirtyData(char* pszNetRcvBufIn, int iNetRcvBufLenIn, int& iSkipLen);


  /*
  * Desc: 
  *     依据输入的网络接收缓冲区,判断是否存在完整的网络包
  *     
  * Pram:
  *     pszNetRcvBufIn     网络接收缓冲区
  *     iNetRcvBufLenIn    网络接收缓冲区长度
  * Retr:
  *     bool               true:有完整网络报文;     false:无完整网络报文
  */ 
  virtual bool IsHasFullPackage(char* pszNetRcvBufIn, int iNetRcvBufLenIn);


  /*
  * Desc: 
  *     依据输入的网络接收缓冲区,解包出第一个完整业务报文输出
  *     在调用该函数之前,必须先调用 IsHasFullPackage(...),且返回值必须为0
  * Pram:
  *     pszNetRcvBufIn     网络接收缓冲区
  *     iNetRcvBufLenIn    网络接收缓冲区长度
  *     pszBodyOut         完整的业务报文        【输出参数,由应用(CommuApplication)负责删除】
  *     iBodyLenOut        业务报文长度(即网络报文体)
  *     iHeadLenOut        网络报文头长度
  *     iTailLenOut        网络报文尾长度
  * Retr:
  *     bool               解包成功返回 true, 解包失败返回 false
  */ 
  virtual bool UnpackNetPackage(char* pszNetRcvBufIn, int iNetRcvBufLenIn, char*& pszBodyOut, int& iBodyLenOut, int& iHeadLenOut, int& iTailLenOut);


};

#include "StdAfx.h"
#include "SzBinaryAnalyzer.h"
#include "MessageStructs.h"
#include "CustBinaryBizClass.h"




CSzBinaryAnalyzer::CSzBinaryAnalyzer(void)
{
  this->m_iNetPackHeadLen = sizeof(BINARY::HEAD);
  this->m_iNetPackTailLen = sizeof(BINARY::TAIL);
}




CSzBinaryAnalyzer::~CSzBinaryAnalyzer(void)
{
}




  /*
  * Desc: 
  *     依据输入的业务报文,打包成网络报文并输出
  *     默认的通讯分析器只含简单的网络层组包解包逻辑逻辑,不包含对于业务协议的包。网络包规则如下:
  *         网络包头包括:包头识别码(换行回车符:'\n\r')+ 一个整型值的长度,无包尾
  *     注:当符合以下条件的情况下可以不调用该接口
  *       1、业务报文件长度小于 TCPConnect中定义的:最大网络接收缓冲区大小
  *       2、对网络包组包规则无特殊要求
  * Pram:
  *     pszBodyIn         业务报文
  *     iBodyLenIn        业务报文长度
  *     pszNetBufOut      网络报文       【输出参数由调用者清除】
  *     iBufLenOut        网络报文长度
  * Retr:
  *     bool              打包成功返回 true, 打包失败返回 false
  */ 
bool CSzBinaryAnalyzer::PackNetPackage(char* pszBodyIn, int iBodyLenIn, char*& pszNetBufOut, int& iBufLenOut)
{
  bool bReturn = false;


  iBufLenOut = iBodyLenIn;


  pszNetBufOut = new char[iBufLenOut+1];
  if (pszNetBufOut == NULL)
  {
//    std::cout<< "分配内存存储打包后的网络报文失败" << std::endl;
  }
  else
  {
    memset(pszNetBufOut, 0x00, iBufLenOut+1);
    memcpy(pszNetBufOut, pszBodyIn, iBodyLenIn);
  }


  bReturn = true;


  return bReturn;
}


    
  /*
  * Desc: 
  *     依据输入的网络接收缓冲区,判断是否存在脏数据需要被清理,并通过返回值iSkipLen告知需要被处理的脏数据长度。
  *     必须实现存在错误包时的应对处理,由(-1:抛弃错误数据,但不断开网络;-2:中断网络)
  *     
  * Pram:
  *     pszNetRcvBufIn     网络接收缓冲区
  *     iNetRcvBufLenIn    网络接收缓冲区长度
  *     iSkipLen           网络接收缓冲区超始位置开始需要被忽略的脏数据长度, 必须正确,否则会导致清楚正确的数据
  * Retr:
  *     int                0:无脏数据  -1:有脏数据但不中断网络, -2:有脏数据需要中断网络
  */ 
  int CSzBinaryAnalyzer::IsExistDirtyData(char* pszNetRcvBufIn, int iNetRcvBufLenIn, int& iSkipLen)
  {
    int iReturn = 0;
    
    if (iNetRcvBufLenIn > m_iNetPackHeadLen)
    {
      unsigned int uiBodyLength = ::ntohl(((BINARY::HEAD*)pszNetRcvBufIn)->BodyLength);


      if (iNetRcvBufLenIn >= ((int)uiBodyLength + m_iNetPackHeadLen + m_iNetPackTailLen))
      {
        unsigned iCheckSum =  ::ntohl(((BINARY::TAIL*)(pszNetRcvBufIn + uiBodyLength + m_iNetPackHeadLen))->CheckSum);
//         if (::ntohl(((BINARY::HEAD*)pszNetRcvBufIn)->MsgType) == BINARY::MsgType_Logon1)
//         {
//           BINARY::CLogon logon;
//           int ilogonLen = logon.GetMessageSize();
//           logon.Deserialize(pszNetRcvBufIn, uiBodyLength+ m_iNetPackHeadLen + m_iNetPackTailLen);
//           int iMessageLen = 0;
//           int IheartBeat = logon.GetLOGINHeartBtInt();
//           unsigned iCheckSumCmp = BINARY::GenerateCheckSum(logon.Serialize(iMessageLen), uiBodyLength+ m_iNetPackHeadLen);
//         }
        unsigned iCheckSumCmp = BINARY::GenerateCheckSum(pszNetRcvBufIn, uiBodyLength+ m_iNetPackHeadLen);
        if (iCheckSum != iCheckSumCmp)
        {
          iReturn = -2;
        }
      }
    }


    return iReturn;
  }




  /*
  * Desc: 
  *     依据输入的网络接收缓冲区,判断是否存在完整的网络包
  *     
  * Pram:
  *     pszNetRcvBufIn     网络接收缓冲区
  *     iNetRcvBufLenIn    网络接收缓冲区长度
  * Retr:
  *     bool               true:有完整网络报文;     false:无完整网络报文
  */ 
  bool CSzBinaryAnalyzer::IsHasFullPackage(char* pszNetRcvBufIn, int iNetRcvBufLenIn)
  {
    bool bReturn = false;


    unsigned int uiBodyLength = ::ntohl(((BINARY::HEAD*)pszNetRcvBufIn)->BodyLength );


    if ( iNetRcvBufLenIn >= ((int)uiBodyLength+ m_iNetPackHeadLen + m_iNetPackTailLen ) )
    {
      bReturn = true;
    }


    return bReturn;
  }




  /*
  * Desc: 
  *     依据输入的网络接收缓冲区,解包出第一个完整业务报文输出
  *     在调用该函数之前,必须先调用 IsHasFullPackage(...),且返回值必须为true
  * Pram:
  *     pszNetRcvBufIn     网络接收缓冲区
  *     iNetRcvBufLenIn    网络接收缓冲区长度
  *     pszBodyOut         完整的业务报文        【输出参数,由应用(CommuApplication)负责删除】
  *     iBodyLenOut        业务报文长度(即网络报文体)
  *     iHeadLenOut        网络报文头长度
  *     iTailLenOut        网络报文尾长度
  * Retr:
  *     bool               解包成功返回 true, 解包失败返回 false
  */ 
  bool CSzBinaryAnalyzer::UnpackNetPackage(char* pszNetRcvBufIn, int iNetRcvBufLenIn, char*& pszBodyOut, int& iBodyLenOut, int& iHeadLenOut, int& iTailLenOut)
  {
    bool bReturn = false;


    unsigned int uiBodyLength = ::ntohl(((BINARY::HEAD*)pszNetRcvBufIn)->BodyLength);


    if (iNetRcvBufLenIn >= ((int)uiBodyLength+ m_iNetPackHeadLen + m_iNetPackTailLen))
    {
      iBodyLenOut = uiBodyLength+ m_iNetPackHeadLen + m_iNetPackTailLen;
      pszBodyOut = new char[iBodyLenOut + 1];
      if (pszBodyOut == NULL) {
//        std::cout<< "分配内存存储解包后的业务报文失败" << std::endl;
      }
      else {
        memset(pszBodyOut, 0x00, iBodyLenOut + 1);
        memcpy(pszBodyOut, pszNetRcvBufIn, iBodyLenOut);
        bReturn = true;
      }
    }


    return bReturn;
  }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值