NetComm-CommuApp

来源:互联网 发布:数据相关法律问题 编辑:程序博客网 时间:2024/05/16 00:19
#pragma once


#include "CommonDefine.h"
class CCommuApplication
{
public:
  CCommuApplication(void);
  virtual ~CCommuApplication(void);


  /*
  * Desc: 
  *     回调返回接收到的完整网络报文
  * Pram:
  *     refConnectInfo     连接参数信息
  *     pszBussBufOut      完整的网络报文        【输入参数,由分析器(CommuAnalyzer)产生,由应用(CommuApplication)负责删除】
  *     iBufLenOut         网络报文长度
  * Retr:
  *     void               无返回
  */ 
  virtual void FromNet(TCPCONNECT::CONNECT_INFO& refConnectInfo, char* pszBussBufOut, int iBufLenOut);
  
  /*
  * Desc: 
  *     回调返回网络事件通知
  * Pram:
  *     refConnectInfo     连接参数信息
  *     enEventType        网络事件类型,参看 TCPCONNECT::EVENT_TYPE 定义
  * Retr:
  *     void               无返回
  */ 
  virtual void NetEvent(TCPCONNECT::CONNECT_INFO& refConnectInfo, int enEventType);

};

#include "StdAfx.h"
#include <iostream>
#include "CommuApplication.h"




CCommuApplication::CCommuApplication(void)
{
}




CCommuApplication::~CCommuApplication(void)
{
}




void CCommuApplication::FromNet(TCPCONNECT::CONNECT_INFO& refConnectInfo, char* pszBussBufOut, int iBufLenOut)
{


  struct TEST_STRUCT
  {
    int i;
    int b;
    double c;
    char sz2[30];
    double d;
  };
  TEST_STRUCT stStruct;
  memcpy(&stStruct, pszBussBufOut, sizeof(stStruct));
  std::cout<< "接收到来自服务端数据包:" << stStruct.sz2 << " i = " << stStruct.i << std::endl;


  static int iCount = 0;
  static int iBefore = 0;
  iCount++;
    if (iCount ==1) 
    {
     iBefore = GetTickCount();
    }
    else if (iCount == 200000) 
    {
      int iLastTime = GetTickCount()- iBefore;
      //std::cout << "接收20万数据,共费时:" << iLastTime << "毫秒" << std::endl;
    }
    else if (iCount ==17)//???
    {
      int i = 0;
    }
    delete[] pszBussBufOut;
    pszBussBufOut = NULL;
}


void CCommuApplication::NetEvent(TCPCONNECT::CONNECT_INFO& refConnectInfo, int enEventType)
{
  //为什么不用switch,case结构
  if (enEventType == (int)TCPCONNECT::EVENT_TYPE::CONNECT_SUCCESS_EVENT)
  {
    //std::cout << "    = 0,   // 连接成功" << std::endl;
    char szBuf[100] = {0};
    strncpy_s(szBuf, "12345567890", 10);
    send(refConnectInfo.iSocketHandle, szBuf, 10, 0);
  }
  if (enEventType == (int)TCPCONNECT::EVENT_TYPE::CONNECT_FAILD_EVENT)
  {
    //std::cout << "SOCKET句柄:" << refConnectInfo.iSocketHandle << "      = 1,   // 连接失败" << std::endl;
  }
  if (enEventType == (int)TCPCONNECT::EVENT_TYPE::LISTEN_SUCCESS_EVENT)
  {
    //std::cout << "SOCKET句柄:" << refConnectInfo.iSocketHandle << "     = 5,   // 侦听成功" << std::endl;
  }
  if (enEventType == (int)TCPCONNECT::EVENT_TYPE::LISTEN_FAILD_EVENT)
  {
    //std::cout << "SOCKET句柄:" << refConnectInfo.iSocketHandle << "       = 6,   // 侦听失败" << std::endl;
  }
  if (enEventType == (int)TCPCONNECT::EVENT_TYPE::CONNECT_GET_IN_EVENT)
  {
    //std::cout << "SOCKET句柄:" << refConnectInfo.iSocketHandle << "     = 7,   // 连接接入" << std::endl;
  }
  if (enEventType == (int)TCPCONNECT::EVENT_TYPE::CONNECT_QUIT_EVENT)
  {
    SOCKADDR_IN localAddrIn;
    int iLocalAddrInLen = sizeof(localAddrIn);
    getsockname(refConnectInfo.iSocketHandle, (sockaddr*)&localAddrIn, &iLocalAddrInLen);
    //std::cout << "SOCKET句柄:" << refConnectInfo.iSocketHandle << "       = 8,   // 连接退出 客户端Port:" << ntohs(localAddrIn.sin_port) <<  std::endl;
  }
  if (enEventType == (int)TCPCONNECT::EVENT_TYPE::CONNECT_BREAKED_EVENT)
  {
    SOCKADDR_IN localAddrIn;
    int iLocalAddrInLen = sizeof(localAddrIn);
    getsockname(refConnectInfo.iSocketHandle, (sockaddr*)&localAddrIn, &iLocalAddrInLen);
    if (ntohs(localAddrIn.sin_port) == 52428)
    {
      int itst = 0;
    }
    //std::cout << "SOCKET句柄:" << refConnectInfo.iSocketHandle << "    = 12   // 断开连接 客户端Port:" << ntohs(localAddrIn.sin_port) <<  std::endl;
  }
  if (enEventType == (int)TCPCONNECT::EVENT_TYPE::HAS_DIRTY_DATA_CLEAR)
  {
    //std::cout << "SOCKET句柄:" << refConnectInfo.iSocketHandle << "    = 50   // 连接上存在脏数据,即时清除:" << ntohs(localAddrIn.sin_port) <<  std::endl;
  }
  if (enEventType == (int)TCPCONNECT::EVENT_TYPE::HAS_DIRTY_DATA_BREAK)
  {
    //std::cout << "SOCKET句柄:" << refConnectInfo.iSocketHandle << "    = 51   // 连接上存在脏数据,断开网络:" << ntohs(localAddrIn.sin_port) <<  std::endl;
  }


}


\

#pragma once
#include <map>
#include <list>
#include <string>
#include <Windows.h>
#include "CommuApplication.h"
#include "CommuAnalyzer.h"
#include "TCPConnect.h"




class CNetCommunication
{
public:
  CNetCommunication(void);
  ~CNetCommunication(void);




public:
  /*
  * Desc: 
  *     设置网络通讯模块参数
  * Pram:
  *     enCommMode      决定网络模块是以服务端还是客户端模式运行
  *     enBlockMode     决定网络模块是否以阻塞或非阻塞模式运行
  *     strIP           服务端模式下表示侦听的IP及端口
  *                     客户端模式下表示远程服务的IP及端口
  *     iCommuTimeout   通讯超时时间(以秒为单位),仅在客户端模式下生效 
  *                     服务端模式下由客户端设置通讯超时告知,并通过SetCommuTimeout()进行设置
  * Retr:
  *     void            无返回
  */
  void SetNetCommParam(TCPCONNECT::COMMUNICATION_MODE& refenCommMode, TCPCONNECT::BLOCKING_MODE& refenBlockMode, std::string& refstrIP, unsigned short& refsiPort, int iCommuTimeout = 0);


  /*
  * Desc: 
  *     注册通讯分析器
  *     默认的通讯分析器只含简单的网络层组包解包逻辑逻辑,不包含对于业务协议的包。网络包规则如下:
  *         网络包头包括:包头识别码(换行回车符:'\n\r')+ 一个整型值的长度,无包尾
  *     注:当符合以下条件的情况下可以不调用该接口
  *       1、业务报文件长度小于 TCPConnect中定义的:最大网络接收缓冲区大小
  *       2、对网络包组包规则无特殊要求
  * Pram:
  *     pclCommuAnalyzer  该分析器必须实现网络包的组包与解包   
  * Retr:
  *     void              无返回
  */
  void RigisterPacker(CCommuAnalyzer* pclCommuAnalyzer);


  /*
  * Desc: 
  *     注册应用对象
  * Pram:
  *     pclCommuAnalyzer     必须实现接收、已经发送通知接口
  *         
  * Retr:
  *     void          无返回
  */
  void RigisterApp(CCommuApplication* pclCommuApplication);


  /*
  * Desc: 
  *     启动通讯模块
  * Pram:
  *     bReconnect    决定是否进行自动重连【仅在客户端模式下生效,服务端模式下采用默认值】
  *     iTimeout      超时时间(以秒为单位)【在客户端模式表示连接超时,服务端模式下表示侦听超时】
  * Retr:
  *     bool          启动成功为 true, 启动失败为 false
  */ 
  bool Start(bool bReconnect = false, int iTimeout = 0);


  /*
  * Desc: 
  *     停止通讯模块
  * Pram:
  *     bEnforce   决定是否强制停止  默认非强制停止
  *         
  * Retr:
  *     bool       停止成功为 true, 停止失败为 false
  */
  bool Stop(bool bEnforce = false);
    
  /*
  * Desc: 
  *     停止某个连接【仅服务端模型下有效】
  * Pram:
  *              
  * Retr:
  *     bool       停止成功为 true, 停止失败为 false
  */
  bool Stop(TCPCONNECT::CONNECT_INFO& stConnectInfo);


  /*
  * Desc: 
  *     发送数据
  * Pram:
  *     refConnectInfo   连接信息
  *     pszData          待发送数据
  *     iDataLen         待发送数据的长度
  * Retr:
  *     bool             发送成功为 true, 发送失败为 false
  */
  bool SendData(TCPCONNECT::CONNECT_INFO& refConnectInfo, char* pszData, int iDataLen);




private:
  /*
  * Desc: 
  *     设置通讯超时,该函数只能由 通讯应用来调用 CCommuApplication
  * Pram:
  *     iCommuTimeout    连接信息      
  * Retr:
  *     void             无返回
  */
  void SetCommuTimeout(int iCommuTimeout){ m_iCommuTimeout = iCommuTimeout; }


private:
  mylib::CMyCriticalSection     m_csCommunication;
  TCPCONNECT::COMMUNICATION_MODE m_enCommMode;
  TCPCONNECT::BLOCKING_MODE      m_enBlockMode;
  std::string        m_strIP;
  unsigned short     m_siPort;
  int                m_iCommuTimeout;           // 通讯超时 控制心跳
  bool               m_bReconnect;
  int                m_iTimeout;                // 超时【客户端模式表示连接超时,服务端模式下表示侦听超时】
  CCommuAnalyzer*    m_pclCommuAnalyzer;
  CCommuApplication* m_pclCommuApplication;


  CTCPConnect*       m_clTcpConnect;


};

#include "StdAfx.h"
#include <assert.h>
#include "NetCommunication.h"
#include "TCPServer.h"
#include "TCPClient.h"
#include <iostream>




CNetCommunication::CNetCommunication(void)
:m_enCommMode(TCPCONNECT::MODE_CLIENT)
,m_enBlockMode(TCPCONNECT::MODE_BLOCKING)
,m_strIP("")
,m_siPort(0)
,m_iCommuTimeout(3)
,m_iTimeout(10)
,m_pclCommuAnalyzer(NULL)
,m_pclCommuApplication(NULL)
,m_clTcpConnect(NULL)
{
}




CNetCommunication::~CNetCommunication(void)
{
}


void CNetCommunication::SetNetCommParam(TCPCONNECT::COMMUNICATION_MODE& refenCommMode, TCPCONNECT::BLOCKING_MODE& refenBlockMode, std::string& refstrIP, unsigned short& refsiPort, int iCommuTimeout)
{
m_enCommMode    = refenCommMode;
m_enBlockMode   = refenBlockMode;
m_strIP         = refstrIP;
m_siPort        = refsiPort;
m_iCommuTimeout = iCommuTimeout;
}


void CNetCommunication::RigisterPacker(CCommuAnalyzer* pclCommuAnalyzer)
{
assert(pclCommuAnalyzer != NULL);
m_pclCommuAnalyzer = pclCommuAnalyzer;
}


void CNetCommunication::RigisterApp(CCommuApplication* pclCommuApplication)
{
assert(pclCommuApplication != NULL);
m_pclCommuApplication = pclCommuApplication;
}


bool CNetCommunication::Start( bool bReconnect, int iTimeout )
{
bool bReturn = false;


mylib::CCriticalSectionGuard myGuard(m_csCommunication);  
if ( m_clTcpConnect != NULL ) 
{
bReturn = true;//已连接
}
else 
{
m_iTimeout = max(3, iTimeout); // 最低3秒的延时
if ( m_enCommMode == TCPCONNECT::MODE_CLIENT ) 
{
m_clTcpConnect = new CTCPClient();
}
else
{
m_clTcpConnect = new CTCPServer();
}


if ( m_clTcpConnect != NULL ) 
{
if ( m_pclCommuAnalyzer == NULL || m_pclCommuApplication == NULL ) 
{
std::cout << "未注册通讯分析器或通讯应用" << std::endl;
}
else 
{
m_clTcpConnect->RigisterPacker(m_pclCommuAnalyzer);
m_clTcpConnect->RigisterApp(m_pclCommuApplication);
//启动连接
bReturn = m_clTcpConnect->Start(m_strIP, m_siPort, m_enBlockMode, bReconnect, m_iTimeout);
if ( !bReturn ) 
{
std::cout << ((m_enCommMode == TCPCONNECT::MODE_CLIENT) ? "客户端":"服务端") << "启动失败" << std::endl;
}
else 
{
std::cout << ((m_enCommMode == TCPCONNECT::MODE_CLIENT) ? "客户端":"服务端") << "启动成功" << std::endl;
bReturn = true;
}
}
if ( !bReturn ) 
{
delete m_clTcpConnect;
m_clTcpConnect = NULL;
}
}
}


return bReturn;
}


bool CNetCommunication::Stop(bool bEnforce)
{
bool bReturn = false;


mylib::CCriticalSectionGuard myGuard(m_csCommunication);  
if (m_clTcpConnect == NULL) 
{
bReturn = true;
}
else 
{
bReturn = m_clTcpConnect->Stop(bEnforce);
if (bReturn == true) 
{
delete m_clTcpConnect;
m_clTcpConnect = NULL;
}
}


return bReturn;
}


bool CNetCommunication::Stop(TCPCONNECT::CONNECT_INFO& stConnectInfo)
{
bool bReturn = false;
mylib::CCriticalSectionGuard myGuard(m_csCommunication);  
if (m_clTcpConnect == NULL)
{
bReturn = true;
}
else
{
if (m_enCommMode == TCPCONNECT::MODE_SERVER)
{
bReturn = ((CTCPServer*)m_clTcpConnect)->StopConnected(stConnectInfo);
}
}
return bReturn;
}


bool CNetCommunication::SendData(TCPCONNECT::CONNECT_INFO& refConnectInfo, char* pszData, int iDataLen)
{
bool bReturn = false;


//mylib::CCriticalSectionGuard myGuard(m_csCommunication); //可能死锁 
bReturn = m_clTcpConnect->SendData(refConnectInfo, pszData, iDataLen);


return bReturn;
}


原创粉丝点击