关于VC网络编程中用 char 发送结构体的说明

来源:互联网 发布:java微信开发 源码 编辑:程序博客网 时间:2024/06/03 09:16
关于VC网络编程中用 char 发送结构体的说明
    在VC中要发送struct的程序,如果需要中间打包的话,首先因该将结构体转换为字节型的。然后再用
send (SOCKET s,const char FAR * buf,int len,int flags)发送。
这里要注意的是buf可以包含\0字符,而且len必须正确。
包含有\0字符的struct中间过程转换成char可能会有问题。
这里是一个字符转换的CLASS

// Buffer.cpp: implementation of the CBuffer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Buffer.h"
#include "Math.h"

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



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

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    CBuffer
//
// DESCRIPTION:    Constructs the buffer with a default size
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
CBuffer::CBuffer()
{
    // Initial size
    m_nSize = 0;

    m_pPtr = m_pBase = NULL;
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    ~CBuffer
//
// DESCRIPTION:    Deallocates the buffer
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
CBuffer::~CBuffer()
{
    if (m_pBase)
        VirtualFree(m_pBase,0,MEM_RELEASE);
}
   

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    Write
//
// DESCRIPTION:    Writes data into the buffer
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
BOOL CBuffer::Write(PBYTE pData, UINT nSize)
{
    ReAllocateBuffer(nSize + GetBufferLen());

    CopyMemory(m_pPtr,pData,nSize);

    // Advance Pointer
    m_pPtr+=nSize;

    return nSize;
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    Insert
//
// DESCRIPTION:    Insert data into the buffer
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
BOOL CBuffer::Insert(PBYTE pData, UINT nSize)
{
    ReAllocateBuffer(nSize + GetBufferLen());

    MoveMemory(m_pBase+nSize,m_pBase,GetMemSize() - nSize);
    CopyMemory(m_pBase,pData,nSize);

    // Advance Pointer
    m_pPtr+=nSize;

    return nSize;
}


////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    Read
//
// DESCRIPTION:    Reads data from the buffer and deletes what it reads
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
UINT CBuffer::Read(PBYTE pData, UINT nSize)
{
    // Trying to byte off more than ya can chew - eh?
    if (nSize > GetMemSize())
        return 0;

    // all that we have
    if (nSize > GetBufferLen())
        nSize = GetBufferLen();

       
    if (nSize)
    {
        // Copy over required amount and its not up to us
        // to terminate the buffer - got that!!!
        CopyMemory(pData,m_pBase,nSize);
       
        // Slide the buffer back - like sinking the data
        MoveMemory(m_pBase,m_pBase+nSize,GetMemSize() - nSize);

        m_pPtr -= nSize;
    }
       
    DeAllocateBuffer(GetBufferLen());

    return nSize;
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    GetMemSize
//
// DESCRIPTION:    Returns the phyical memory allocated to the buffer
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
UINT CBuffer::GetMemSize()
{
    return m_nSize;
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    GetBufferLen
//
// DESCRIPTION:    Get the buffer 'data' length
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
UINT CBuffer::GetBufferLen()
{
    if (m_pBase == NULL)
        return 0;

    int nSize =
        m_pPtr - m_pBase;
    return nSize;
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    ReAllocateBuffer
//
// DESCRIPTION:    ReAllocateBuffer the Buffer to the requested size
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
UINT CBuffer::ReAllocateBuffer(UINT nRequestedSize)
{
    if (nRequestedSize < GetMemSize())
        return 0;

    // Allocate new size
    UINT nNewSize = (UINT) ceil(nRequestedSize / 1024.0) * 1024;

    // New Copy Data Over
    PBYTE pNewBuffer = (PBYTE) VirtualAlloc(NULL,nNewSize,MEM_COMMIT,PAGE_READWRITE);

    UINT nBufferLen = GetBufferLen();
    CopyMemory(pNewBuffer,m_pBase,nBufferLen);

    if (m_pBase)
        VirtualFree(m_pBase,0,MEM_RELEASE);


    // Hand over the pointer
    m_pBase = pNewBuffer;

    // Realign position pointer
    m_pPtr = m_pBase + nBufferLen;

    m_nSize = nNewSize;

    return m_nSize;
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    DeAllocateBuffer
//
// DESCRIPTION:    DeAllocates the Buffer to the requested size
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
UINT CBuffer::DeAllocateBuffer(UINT nRequestedSize)
{
    if (nRequestedSize < GetBufferLen())
        return 0;

    // Allocate new size
    UINT nNewSize = (UINT) ceil(nRequestedSize / 1024.0) * 1024;

    if (nNewSize < GetMemSize())
        return 0;

    // New Copy Data Over
    PBYTE pNewBuffer = (PBYTE) VirtualAlloc(NULL,nNewSize,MEM_COMMIT,PAGE_READWRITE);

    UINT nBufferLen = GetBufferLen();
    CopyMemory(pNewBuffer,m_pBase,nBufferLen);

    VirtualFree(m_pBase,0,MEM_RELEASE);

    // Hand over the pointer
    m_pBase = pNewBuffer;

    // Realign position pointer
    m_pPtr = m_pBase + nBufferLen;

    m_nSize = nNewSize;

    return m_nSize;
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    Scan
//
// DESCRIPTION:    Scans the buffer for a given byte sequence
//
// RETURNS:        Logical offset
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
int CBuffer::Scan(PBYTE pScan,UINT nPos)
{
    if (nPos > GetBufferLen() )
        return -1;

    PBYTE pStr = (PBYTE) strstr((char*)(m_pBase+nPos),(char*)pScan);
   
    int nOffset = 0;

    if (pStr)
        nOffset = (pStr - m_pBase) + strlen((char*)pScan);

    return nOffset;
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    ClearBuffer
//
// DESCRIPTION:    Clears/Resets the buffer
//
// RETURNS:   
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
void CBuffer::ClearBuffer()
{
    // Force the buffer to be empty
    m_pPtr = m_pBase;

    DeAllocateBuffer(1024);
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    Write
//
// DESCRIPTION:    Writes a string a the end of the buffer
//
// RETURNS:   
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
BOOL CBuffer::Write(CString& strData)
{
    int nSize = strData.GetLength();
    return Write((PBYTE) strData.GetBuffer(nSize), nSize);
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    Insert
//
// DESCRIPTION:    Insert a string at the beginning of the buffer
//
// RETURNS:   
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
BOOL CBuffer::Insert(CString& strData)
{
    int nSize = strData.GetLength();
    return Insert((PBYTE) strData.GetBuffer(nSize), nSize);
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    Copy
//
// DESCRIPTION:    Copy from one buffer object to another...
//
// RETURNS:   
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
void CBuffer::Copy(CBuffer& buffer)
{
    int nReSize = buffer.GetMemSize();
    int nSize = buffer.GetBufferLen();
    ClearBuffer();
    ReAllocateBuffer(nReSize);

    m_pPtr = m_pBase + nSize;

    CopyMemory(m_pBase,buffer.GetBuffer(),buffer.GetBufferLen());
}

////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    GetBuffer
//
// DESCRIPTION:    Returns a pointer to the physical memory determined by the offset
//
// RETURNS:   
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
PBYTE CBuffer::GetBuffer(UINT nPos)
{
    return m_pBase+nPos;
}


////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    GetBuffer
//
// DESCRIPTION:    Returns a pointer to the physical memory determined by the offset
//
// RETURNS:   
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
///////////////////////////////////////////////////////////////////////////////
void CBuffer::FileWrite(const CString& strFileName)
{
    CFile file;

    if (file.Open(strFileName, CFile::modeWrite | CFile::modeCreate))
    {
        file.Write(m_pBase,GetBufferLen());
        file.Close();
    }
}



////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION:    Delete
//
// DESCRIPTION:    Delete data from the buffer and deletes what it reads
//
// RETURNS:       
//
// NOTES:   
//
// MODIFICATIONS:
//
// Name                Date        Version        Comments
// N T ALMOND       270400        1.0            Origin
//
////////////////////////////////////////////////////////////////////////////////
UINT CBuffer::Delete(UINT nSize)
{
    // Trying to byte off more than ya can chew - eh?
    if (nSize > GetMemSize())
        return 0;

    // all that we have
    if (nSize > GetBufferLen())
        nSize = GetBufferLen();

       
    if (nSize)
    {
        // Slide the buffer back - like sinking the data
        MoveMemory(m_pBase,m_pBase+nSize,GetMemSize() - nSize);

        m_pPtr -= nSize;
    }
       
    DeAllocateBuffer(GetBufferLen());

    return nSize;
}