⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netmessage.cpp

📁 这是一个简单的使用WinAPI基于WinSock的ICP/IP程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// NetMsg.cpp: implementation of the CNetMsg class.
//
// Written by Marat Bedretdinov (maratb@hotmail.com)
// Copyright (c) 2000.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// If the source code in  this file is used in any commercial application 
// then acknowledgement must be made to the author of this file 
// and permissions to use this file are requested from the author
//
// (in whatever form you wish).// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage whatsoever.
// It's free - so you get what you pay for.//

#include "stdafx.h"
#include "NetMessage.h"
#include "NetStream.h"
#include "NetConnection.h"

#ifdef _WIN32
  #ifdef _DEBUG
  #undef THIS_FILE
  static char THIS_FILE[]=__FILE__;
  #define new DEBUG_NEW
  #endif
#endif  

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CNetObject::CNetObject():
m_pData(0),
m_nSeekRead(0),
m_nSeekWrite(0)
{
}

CNetObject::~CNetObject() 
{
// the m_pData is released with the object
  EmptyBuffer();
}

void CNetObject::EmptyBuffer()
{
  m_nSeekRead   = 0;
  m_nSeekWrite  = 0;

  if (m_pData) {
    delete (char*)m_pData;
    m_pData = 0;  
  }
}

CNetObject& CNetObject::operator=(const CNetObject& obj)
{
  EmptyBuffer();

// if the buffer is empty just copy the member variables
  if (!obj.m_pData) 
	return (*this).operator=(obj);

// reallocate the buffer
  AllocateData(obj.GetSize_Write());
// and copy the context
  memcpy(m_pData, obj.m_pData, obj.GetSize_Write());

  m_nSeekRead   = obj.m_nSeekRead;
  m_nSeekWrite  = obj.m_nSeekWrite;
// copy the member variables
  return operator=(obj);
}

bool CNetObject::operator==(const CNetObject& obj)
{
  return operator==(obj);
}

void* CNetObject::AllocateData(const ulong nSz /* = 0*/)
{
// delete the data
  EmptyBuffer();
// allocate it, using nSz, or GetSize() if nSz == 0
  if (nSz)
    m_pData = malloc(nSz);
  else
    m_pData = malloc(GetSize_Write());
// return it
  return m_pData;
}

bool CNetObject::IsBufferEmpty() const
{
  if (!m_pData) return true;
  return false;
}

bool CNetObject::CheckReadBound(ulong nSz) const
{
  if (m_nSeekRead + nSz <= GetSize_Read()) return true;
  return false;
}

bool CNetObject::CheckWriteBound(ulong nSz) const
{
  if (m_nSeekWrite + nSz <= GetSize_Write()) return true;
  return false;
}

bool CNetObject::Get(ulong& Out)
{
  if (!CheckReadBound(GetSize_ulong())) return false;
  memcpy(&Out, (char*)m_pData + m_nSeekRead, GetSize_ulong());
  Out = ntohl(Out);
  m_nSeekRead += GetSize_ulong();
  return true;
}

bool CNetObject::Get(ushort& Out)
{
  if (!CheckReadBound(GetSize_ushort())) return false;
  memcpy(&Out, (char*)m_pData + m_nSeekRead, GetSize_ushort());
  Out = ntohs(Out);
  m_nSeekRead += GetSize_ushort();
  return true;
}

bool CNetObject::Get(bool& Out)
{
  if (!CheckReadBound(GetSize_bool())) return false;
  memcpy(&Out, (char*)m_pData + m_nSeekRead, GetSize_bool());
  m_nSeekRead += GetSize_bool();
  return true;
}

bool CNetObject::Get(string& Out, ulong nSz)
{
  if (!CheckReadBound(nSz)) return false;
// the buffer does not have a NULL character
  char* pBuff = new char[nSz+1];
  memcpy(pBuff, (char*)m_pData + m_nSeekRead, nSz);
// so add it
  pBuff[nSz] = NULL;
  Out = pBuff;
  delete pBuff;
  m_nSeekRead += nSz;
  return true;
}

bool CNetObject::Get(char* Out, ulong nSz)
{
  if (!CheckReadBound(nSz)) return false;
// the buffer does not have a NULL character
  char* pBuff = new char[nSz+1];
  memcpy(pBuff, (char*)m_pData + m_nSeekRead, nSz);
// so add it
//  pBuff[nSz] = NULL;
  memcpy(Out, pBuff, nSz);
  delete pBuff;
  m_nSeekRead += nSz;
  return true;
}

bool CNetObject::Put(const ulong In)
{
  if (!CheckWriteBound(GetSize_ulong())) return false;
  ulong nul = htonl(In);
  memcpy((char*)m_pData + m_nSeekWrite, &nul, GetSize_ulong());
  m_nSeekWrite += GetSize_ulong();
  return true;
}

bool CNetObject::Put(const ushort In)
{
  if (!CheckWriteBound(GetSize_ushort())) return false;
  ushort nus = htons(In);
  memcpy((char*)m_pData + m_nSeekWrite, &nus, GetSize_ushort());
  m_nSeekWrite += GetSize_ushort();
  return true;
}

bool CNetObject::Put(const bool In)
{
  if (!CheckWriteBound(GetSize_bool())) return false;
  memcpy((char*)m_pData + m_nSeekWrite, &In, GetSize_bool());
  m_nSeekWrite += GetSize_bool();
  return true;
}

bool CNetObject::Put(const string& In, ulong nSz)
{
  if (!CheckWriteBound(nSz)) return false;
// the NULL character is excluded
  memcpy((char*)m_pData + m_nSeekWrite, In.c_str(), nSz);
  m_nSeekWrite += nSz;
  return true;
}

bool CNetObject::Put(const char* In, ulong nSz)
{
  if (!CheckWriteBound(nSz)) return false;
// the NULL character is excluded
  memcpy((char*)m_pData + m_nSeekWrite, In, nSz);
  m_nSeekWrite += nSz;
  return true;
}

////////////////////////// CNetMsgHdr ////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CNetMsgHdr::CNetMsgHdr():
CNetObject()
{
  m_data.m_strSignature = NET_SIGNATURE;
  m_data.m_nHost = 0;
  m_data.m_nRemote = 0;
  m_data.m_nClassId = 0;
  m_data.m_nMsgSize = 0;
}

CNetMsgHdr::CNetMsgHdr(const CNetMsgHdr& obj):
CNetObject()
{
  operator=(obj);
}

CNetObject& CNetMsgHdr::operator=(const CNetObject& obj) 
{
  const CNetMsgHdr& msg = dynamic_cast<const CNetMsgHdr&>(obj);
// copies the MSG structure
  m_data.m_strSignature = msg.m_data.m_strSignature;
  m_data.m_nHost                = msg.m_data.m_nHost;
  m_data.m_nRemote              = msg.m_data.m_nRemote;
  m_data.m_nClassId             = msg.m_data.m_nClassId;
  m_data.m_nMsgSize             = msg.m_data.m_nMsgSize;

  return *this;
}

bool CNetMsgHdr::operator==(const CNetObject& obj)
{
  const CNetMsgHdr& msg = dynamic_cast<const CNetMsgHdr&>(obj);
// compares the MSG structure
  if ( !m_data.m_strSignature.compare(msg.m_data.m_strSignature) &&
       m_data.m_nHost            == msg.m_data.m_nHost &&
           m_data.m_nRemote              == msg.m_data.m_nRemote &&
           m_data.m_nClassId     == msg.m_data.m_nClassId &&
           m_data.m_nMsgSize     == msg.m_data.m_nMsgSize)
    return true;
  return false;
}

CNetMsgHdr::~CNetMsgHdr()
{
}

void CNetMsgHdr::Read()
{
  if 
  (
        !Get(m_data.m_strSignature, SIGNATURE_SIZE)                                     ||
        !Get(m_data.m_nHost)                                                                            ||
        !Get(m_data.m_nRemote)                                                                          ||
        !Get(m_data.m_nClassId)                                                                         ||
        !Get(m_data.m_nMsgSize) 
 )
// if something went wrong
        throw CNetMsgException(ERR_NET_MSG_DATA_CORRUPTED, "void CNetMsgHdr::Read()");

// check the signature
  if (m_data.m_strSignature.compare(NET_SIGNATURE))
        throw CNetMsgException(ERR_NET_WRONG_SIGNATURE, "void CNetMsgHdr::Read()");
}

void CNetMsgHdr::Write()
{
  if
  (
   !Put(m_data.m_strSignature, SIGNATURE_SIZE)                                     ||
   !Put(m_data.m_nHost)                                                                            ||
   !Put(m_data.m_nRemote)                                                                          ||
   !Put(m_data.m_nClassId)                                                                         ||
   !Put(m_data.m_nMsgSize)
  )
// if something went wrong
    throw CNetMsgException(ERR_NET_MSG_DATA_CORRUPTED, "void CNetMsgHdr::Write()");
}

void CNetMsgHdr::SetHost(const char* strAddr)
{
  ulong nAddr = g_addr_stu(strAddr);
  m_data.m_nHost = nAddr;
}

void CNetMsgHdr::SetRemote(const char* strAddr)
{
  ulong nAddr = g_addr_stu(strAddr);
  m_data.m_nRemote = nAddr;
}

void CNetMsgHdr::SetHost(ulong nAddr)
{
  m_data.m_nHost = nAddr;
}

void CNetMsgHdr::SetRemote(ulong nAddr)
{
  m_data.m_nRemote = nAddr;
}

const string CNetMsgHdr::GetHost() const
{
  string strAddr = g_addr_uts(m_data.m_nHost);
  return strAddr;
}

const string CNetMsgHdr::GetRemote() const
{
  string strAddr = g_addr_uts(m_data.m_nRemote);
  return strAddr;
}

void CNetMsgHdr::Dump(ostream& os)
{
  // save old seek position
  ulong nSavPos = m_nSeekRead;

  ulong data = 0;
  os << endl << "Start Dump for CNetMsgHdr:" << endl << endl;

  os << "Dump for the buffer:" << endl << endl;
  if (Get(data)) 
        os << "CNetMsgHdr::m_data::m_strSignature = " << data << ";" << endl;
  if (Get(data)) 
        os << "CNetMsgHdr::m_data::m_nHost        = " << data << ";" << endl;
  if (Get(data)) 
        os << "CNetMsgHdr::m_data::m_nRemote  = " << data << ";" << endl;
  if (Get(data)) 
        os << "CNetMsgHdr::m_data::m_nClassId     = " << data << ";" << endl;
  if (Get(data)) 
        os << "CNetMsgHdr::m_data::m_nMsgSize     = " << data << ";" << endl;

// restore old seek position
  m_nSeekRead = nSavPos;

  os << "Dump for the member variables:" << endl << endl;
  os << "CNetMsgHdr::m_data::m_strSignature = " <<  m_data.m_strSignature.c_str() << ";" << endl;
  os << "CNetMsgHdr::m_data::m_nHost      = " <<  m_data.m_nHost << ";" << endl;
  os << "CNetMsgHdr::m_data::m_nRemote    = " <<  m_data.m_nRemote << ";" << endl;
  os << "CNetMsgHdr::m_data::m_nClassId   = " <<  m_data.m_nClassId << ";" << endl;
  os << "CNetMsgHdr::m_data::m_nMsgSize   = " <<  m_data.m_nMsgSize << ";" << endl;

  os << endl << "End Dump for CNetMsgHdr:" << endl << endl;
}

//////////////////////////// CNetMsg /////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CNetMsg::CNetMsg()
{
}

CNetMsg::CNetMsg(const CNetMsg& obj):
CNetObject()
{
  operator=(obj);
}

CNetObject& CNetMsg::operator=(const CNetObject& obj) 
{
//  CNetObject::operator=(obj);
// copies the CNetMsgHdr data and the data buffer
  const CNetMsg& msg = dynamic_cast<const CNetMsg&>(obj);
  m_header = msg.m_header;
//  return operator=(msg);
  return *this;
}

bool CNetMsg::operator==(const CNetObject& obj)
{
// compares the CNetMsgHdr data and the data buffers
  const CNetMsg& msg = dynamic_cast<const CNetMsg&>(obj);
  if (!(m_header == msg.m_header)) return false;
// compare the rest of the message data
  return operator==(msg);
}

CNetMsg::~CNetMsg()
{
}

void CNetMsg::EmptyBuffer()
{
  CNetObject::EmptyBuffer();
}
/*
void CNetMsg::Read()
{
// read header's data from void*
  m_header.Read();
// read message data from void*
  ReadBody();
}
*/
// reads m_header from CNetStream*, then creates a message
// and reads data of the message from the stream
void CNetMsg::Read(CNetStream* pStream, CNetMsg*& pMsg)
{
  CNetMsgHdr header;
// read the header data. CNetMsgHdr::m_pData now points to the data
  pStream->GetConnection()->Read(header.AllocateData(), header.GetSize_Read());
// parse out the member variables from m_pData
  header.Read();
// create the message class based on the message class name
  pMsg = pStream->CreateMessage(header.GetMSG().m_nClassId);
  if (!pMsg) 
    throw CNetMsgException(ERR_NET_MSG_UKNOWN_TYPE, "CNetMsg*  CNetMsg::Read(CNetStream* pStream)");
// release header.m_pData, because if I don't, then the CNetMsgHdr::operator=()
// will allocate a new m_pData for pMsg->m_header::m_pData and copy 
// the context. That would be an overkill. I don't need this info anymore, 
// since the member variables are properly populated already
   header.EmptyBuffer();
// copy header's member variables
   pMsg->GetMsgHdr()->operator=(header);
// now read the message body data. CNetMsg[derived]::m_pData now points to the data
   pStream->GetConnection()->Read(pMsg->AllocateData(header.GetMsgSize()), header.GetMsgSize());
// parse out the member variables from m_pData
   pMsg->ReadBody();
   if (pMsg->HasChildren())
	 pMsg->ReadChildren(pStream);
// release the message's m_Data
   pMsg->EmptyBuffer();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -