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

📄 msocketbase.cpp

📁 跨平台C++基础库
💻 CPP
字号:

#include "MCRT/msocketbase.h"

#ifndef WIN32 //! WIN32
#   include <sys/types.h>
#   include <sys/socket.h>
#   include <netinet/in.h>
#   include <netdb.h>
#   include <unistd.h>
#   include <errno.h>
#endif //end WIN32

#include <time.h>

bool MSocketBase::m_bInitialized    =   false;

MSocketBase::MSocketBase()
:m_timeoutSend(M_TIMEOUT_SEND_RECV), m_timeoutRecv(M_TIMEOUT_SEND_RECV),
 m_nCountKeepAlive( M_TIMEOUT_KEEPALIVE )
{
    this->m_socket  =   M_INVALID_SOCKET;
}

MSocketBase::~MSocketBase()
{
}

mInt32 MSocketBase::Init()
{
    if ( MSocketBase::m_bInitialized )
    {
        return E_SUCCESS;
    }

#ifdef WIN32
    WSADATA wsaData;
    if ( ::WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0 )
    {
        return  E_SOCKET_LOAD_LIB;
    }
#endif //end WIN32
    MSocketBase::m_bInitialized =   true;

    return E_SUCCESS;
}

mInt32 MSocketBase::Fini()
{
    if ( ! MSocketBase::m_bInitialized )
    {
        return E_SUCCESS;
    }

#ifdef WIN32
    ::WSACleanup();
#endif //end WIN32

    return E_SUCCESS;
}

mInt32 MSocketBase::GetHostName( char* pBuf, mInt32 lenBuf )
{
    ::gethostname( pBuf, lenBuf );

    return E_SUCCESS;
}

mInt32 MSocketBase::Close()
{
    if ( this->IsValidSocket() )
    {
        ::MCloseSocket( this->m_socket );
        this->m_socket  =   M_INVALID_SOCKET;
    }

    return E_SUCCESS;
}

//available in winsock2 under win32
mInt32 MSocketBase::SetTimeoutSend( mUInt32 nCount )
{
#ifndef WIN32

#ifdef WIN32
    struct  timeval time_out;
    time_out.tv_sec     =   nCount / 1000;
    time_out.tv_usec    =   (nCount % 1000) * 1000;
#else //! WIN32
    mInt32  time_out    =   (mInt32)nCount;
#endif //end WIN32

    if ( ::setsockopt( this->m_socket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&time_out, sizeof(time_out) ) != 0 )
    {
        return E_SOCKET_SETOPT;
    }

#endif //end WIN32

    return E_SUCCESS;
}

//available in winsock2 under win32
mInt32 MSocketBase::SetTimeoutRecv( mUInt32 nCount )
{
#ifndef WIN32

#ifdef WIN32
    struct  timeval time_out;
    time_out.tv_sec     =   nCount / 1000;
    time_out.tv_usec    =   (nCount % 1000) * 1000;
#else //! WIN32
    mInt32  time_out    =   (mInt32)nCount;
#endif //end WIN32

    this->m_timeoutRecv =   (mInt32)nCount;

    if ( ::setsockopt( this->m_socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&time_out, sizeof(time_out) ) != 0 )
    {
        return E_SOCKET_SETOPT;
    }

#endif //end WIN32

    return E_SUCCESS;
}

mInt32 MSocketBase::SetTimeoutKeepAlive( mUInt32 nCount )
{
    this->m_nCountKeepAlive =   nCount / this->m_timeoutRecv;

    return E_SUCCESS;
}

mInt32 MSocketBase::Send( const char* pData, mUInt32 dataLen )
{
    if ( ! this->IsValidSocket() )
    {
        return E_SOCKET_INVALID_STATE;
    }

    mInt32  retVal      =   E_SUCCESS;

    mInt32  bytesSent   =   0;
    mInt32  bytesUnit   =   0;

    while ( bytesSent != dataLen )
    {
        if ( (dataLen - bytesSent) <= M_MAX_PACKET_LEN ) //normal
        {
            bytesUnit   =   ::send( this->m_socket, pData + bytesSent, dataLen - bytesSent, 0 );
        }
        else //data is so long, truncate it
        {
            bytesUnit   =   ::send( this->m_socket, pData + bytesSent, M_MAX_PACKET_LEN, 0 );
        }

        if ( bytesUnit > 0 ) //normal
        {
            bytesSent   +=  bytesUnit;
        }
        else if ( bytesUnit == 0 ) //peer closed the connection
        {
            retVal  =   E_SOCKET_PEER_CLOSED;
            break;
        }
        else //maybe timeout
        {
            retVal  =   E_SOCKET_TIMEOUT;
            break;
        }

        retVal  =   bytesSent;
    }

    return retVal;
}

mInt32 MSocketBase::Recv( char* pBuf, mUInt32 bufLen, bool bFixedLen )
{
    if ( ! this->IsValidSocket() )
    {
        return E_SOCKET_INVALID_STATE;
    }

    mInt32  retVal      =   -1;
    mInt32  bytesRecv   =   0;
    if ( ! bFixedLen ) // receive any size data
    {
        bytesRecv   =   ::recv( this->m_socket, pBuf, bufLen, 0 );

        if ( bytesRecv == 0 ) //peer closed the connection
        {
            retVal  =   E_SOCKET_PEER_CLOSED;
        }
        else if ( bytesRecv < 0 ) //maybe timeout
        {
            retVal  =   E_SOCKET_TIMEOUT;
        }

        retVal  =   bytesRecv;
    }
    else // receive full buffer data
    {
        mInt32  bytesUnit   =   0;

        while ( bytesRecv != bufLen )
        {
            if ( (bufLen - bytesRecv) <= M_MAX_PACKET_LEN ) //normal
            {
                bytesUnit   =   ::recv( this->m_socket, pBuf + bytesRecv, bufLen - bytesRecv, 0 );
            }
            else //data is so long, truncate it
            {
                bytesUnit   =   ::recv( this->m_socket, pBuf + bytesRecv, M_MAX_PACKET_LEN, 0 );
            }

            if ( bytesUnit > 0 ) //normal
            {
                bytesRecv   +=  bytesUnit;
            }
            else if ( bytesUnit == 0 ) //peer closed the connection
            {
                retVal  =   E_SOCKET_PEER_CLOSED;
                break;
            }
            else //maybe timeout
            {
                retVal  =   E_SOCKET_TIMEOUT;
                break;
            }
        }

        retVal  =   bytesRecv;
    }

    return retVal;
}

bool MSocketBase::IsValidSocket()
{
    if ( this->m_socket != M_INVALID_SOCKET )
    {
        return true;
    }

    return false;
}

⌨️ 快捷键说明

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