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

📄 cconnection.cpp

📁 wince 下网络通讯类
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    timeval	timeout;

    //	设置成无信号
    ResetEvent ( m_event );

    m_sync.Lock ();
    SOCKET s = m_socket;
    m_socket = INVALID_SOCKET;
    m_sync.UnLock ();

    /*
    #define SD_RECEIVE      0x00
    #define SD_SEND         0x01
    #define SD_BOTH         0x02
    */
    shutdown ( s, 0x01 );

    FD_ZERO ( &readfds );
    FD_SET ( s, &readfds );

    timeout.tv_sec = TIMEOUT;
    timeout.tv_usec = 0;

    status = select ( 1, &readfds, NULL, NULL, &timeout );

    if ( status == SOCKET_ERROR )
    {
        int err = WSAGetLastError();
        CError::GetErrorString ( err );
    }


    WaitForSingleObject ( m_hRecvThread, 500 );

    closesocket ( s );

    DWORD dwExitCode;

    GetExitCodeThread ( m_hRecvThread, &dwExitCode );

    if ( dwExitCode == STILL_ACTIVE )
    {
        WaitForSingleObject ( m_event, 500 );
        ResetEvent ( m_event );

        TerminateThread ( m_hRecvThread, 0 );
    }

    CloseHandle ( m_hRecvThread );

    m_hRecvThread = NULL;
}

bool CConnection::PeerInfo ( char* host, int host_len, unsigned int* port )
{
    if ( !IsConnected () )
    {
        CError::GetErrorString ( WSAENOTCONN );
        return false;
    }

    sockaddr_in addr;

    m_sync.Lock ();
    addr = m_addr;
    m_sync.UnLock ();

    if ( port != NULL )
        *port = ( unsigned int ) ntohs ( addr.sin_port );

    if ( host != NULL )
    {
        char* ip = inet_ntoa ( addr.sin_addr );

        memset ( host, 0, host_len );

        int uselen = strlen ( ip ) + 1;

        if ( host_len < uselen ) uselen = host_len;

        memcpy ( host, ip, host_len );
    }

    return true;
}

int CConnection::Send ( const char* buffer, int bufferlen )
{
    if ( !IsConnected () )
    {
        CError::GetErrorString ( WSAENOTCONN );
        return 0;
    }

    m_sync.Lock ();

    SOCKET sock = m_socket;
    m_sync.UnLock ();

    return send ( sock, buffer, bufferlen, 0 );
}

int CConnection::Receive ( char* buffer, int bufferlen )
{
    int iRecvd;

    m_sync.Lock ();
    iRecvd = m_data.Remove ( buffer, bufferlen );
    m_sync.UnLock ();

    return iRecvd;
}

void CConnection::SetCloseFunc ( CALLBACKFUNC hFunc )
{
    m_sync.Lock ();
    m_hCloseFunc = hFunc;
    m_sync.UnLock ();
}

void CConnection::SetCloseEvent ( HANDLE hEvent )
{
    m_sync.Lock ();
    m_hCloseEvent = hEvent;
    m_sync.UnLock ();
}

void CConnection::SetReceiveFunc ( CALLBACKFUNC hFunc )
{
    m_sync.Lock ();
    m_hRecvFunc = hFunc;
    m_sync.UnLock ();
}

void CConnection::SetReceiveEvent ( HANDLE hEvent )
{
    m_sync.Lock ();
    m_hRecvEvent = hEvent;
    m_sync.UnLock ();
}

bool CConnection::IsConnected ()
{
    bool bConnd;

    m_sync.Lock ();
    bConnd = m_socket != INVALID_SOCKET;
    m_sync.UnLock ();

    return bConnd;
}

int CConnection::HasReceived ()
{
    int iRecvd;

    m_sync.Lock ();
    iRecvd = m_data.Length ();
    m_sync.UnLock ();

    return iRecvd;
}

int CConnection::RecvWait ()
{
    int		status = 0;
    char	buffer[RECVSIZE];
    SOCKET	sock;


    while ( true )
    {
        m_sync.Lock ();
        sock = m_socket;
        m_sync.UnLock ();

        if ( sock == INVALID_SOCKET )
        {
            SetEvent ( m_event );
            return 0;
        }

        memset ( buffer, 0, RECVSIZE );

        status = recv ( sock, buffer, RECVSIZE, 0 );

        if ( status == SOCKET_ERROR )
        {
            int err = WSAGetLastError();
            CError::GetErrorString ( err );

            if ( m_hCloseEvent ) SetEvent ( m_hCloseEvent );

            // Disconnect ();

            SetEvent ( m_event );

            if ( m_hCloseFunc ) ( m_hCloseFunc ) ( ( DWORD ) this );

            return 0;
        }

        if ( status > 0 )
        {
            m_sync.Lock ();
            m_data.Append ( buffer, status );

            HANDLE hEvent = m_hRecvEvent;
            CALLBACKFUNC fncCallback = m_hRecvFunc;
            m_sync.UnLock ();

            if ( hEvent ) SetEvent ( hEvent );

            if ( fncCallback ) ( fncCallback ) ( ( DWORD ) this );
        }
        else
        {

            //   Disconnect ();

            SetEvent ( m_event );

            if ( m_hCloseEvent ) SetEvent ( m_hCloseEvent );

            if ( m_hCloseFunc ) ( m_hCloseFunc ) ( ( DWORD ) this );

            return 0;

        }
    }

    return 0;
}

int CConnection::RecvThread ( void* pThis )
{
    return ( ( CConnection* ) ( pThis ) )->RecvWait ();
}





CNetworking::CConnectionList::CConnectionList ()
{
    m_first = NULL;
    m_last = NULL;
    m_length = 0;
}

CNetworking::CConnectionList::~CConnectionList ()
{
    if ( m_length == 0 ) return;

    Node* next = m_first->m_next;

    do
    {
        delete m_first;
        m_first = next;

        if ( m_first )
            next = m_first->m_next;
    }
    while ( m_first );
}

void CNetworking::CConnectionList::Add ( CConnection* con )
{
    if ( m_length == 0 )
    {
        m_last = m_first = new Node ();
    }
    else
    {
        m_last->m_next = new Node ();
        m_last = m_last->m_next;
    }

    m_last->m_con = con;

    m_length ++;
}


CConnection* CNetworking::CConnectionList::Remove ()
{
    if ( m_length == 0 ) return NULL;

    CConnection* ret = m_first->m_con;

    Node* newfirst = m_first->m_next;

    delete m_first;

    m_first = newfirst;

    m_length --;

    return ret;
}


CConnection* CNetworking::CConnectionList::Remove ( int i )
{
    if ( m_length == 0 ) return NULL;

    if ( i == 0 ) return Remove ();

    Node* ret = m_first;

    for ( int j = 0; j < i - 1; j++ )
        ret = ret->m_next;

    Node* d = ret->m_next;

    CConnection* cret = d->m_con;

    ret->m_next = d->m_next;

    delete d;

    m_length --;

    return cret;
}

CConnection* CNetworking::CConnectionList::Item ( int i )
{
    return operator[] ( i );
}

CConnection* CNetworking::CConnectionList::operator [] ( int i )
{
    if ( m_length == 0 ) return NULL;

    Node* ret = m_first;

    for ( int j = 0; j < i; j++ )
        ret = ret->m_next;

    return ret->m_con;
}

long CNetworking::CConnectionList::Length ()
{
    return m_length;
}


CNetworking::CConnectionList::Node::Node ()
{
    m_con = NULL;
    m_next = NULL;
}




CConnection::CDataStack::CDataStack ()
{
    m_buffer = NULL;
    m_length = 0;
}

CConnection::CDataStack::~CDataStack ()
{
    delete[] m_buffer;
}

void CConnection::CDataStack::Append ( const char* data, int len )
{
    if ( data == NULL || len <= 0 ) return;

    m_sync.Lock ();

    if ( m_length == 0 )
    {
        m_buffer = new char[len];
        memcpy ( m_buffer, data, len );
        m_length = len;
    }
    else
    {

        char* oldbuff = new char[m_length];
        memcpy ( oldbuff, m_buffer, m_length );

        delete[] m_buffer;
        m_buffer = new char[m_length + len];

        memcpy ( m_buffer, oldbuff, m_length );
        memcpy ( &m_buffer[m_length], data, len );

        m_length += len;

        delete[] oldbuff;
    }

    m_sync.UnLock ();
}

int CConnection::CDataStack::Remove ( char* data, int len )
{
    memset ( data, 0, len );

    m_sync.Lock ();

    if ( m_length == 0 )
    {
        m_sync.UnLock ();
        return 0;
    }

    int remlen = len;

    if ( remlen > m_length )
        remlen = m_length;

    char* oldbuff = new char[m_length];

    memcpy ( oldbuff, m_buffer, m_length );

    memcpy ( data, oldbuff, remlen );

    delete[] m_buffer;

    if ( m_length - remlen <= 0 )
    {
        m_buffer = NULL;
        m_length = 0;
    }
    else
    {
        m_buffer = new char[m_length - remlen];

        memcpy ( m_buffer, &oldbuff[remlen], m_length - remlen );

        m_length -= remlen;
    }

    delete[] oldbuff;

    m_sync.UnLock ();

    return remlen;
}

int CConnection::CDataStack::Length ()
{
    long length;

    m_sync.Lock ();
    length = m_length;
    m_sync.UnLock ();

    return length;
}


CSync::CSync ()
{
    m_sync = CreateMutex ( NULL, false, NULL );

    if ( m_sync == NULL )
        CError::GetErrorString ( 1001 );
}

CSync::~CSync()
{
    if ( m_sync != NULL )
    {
        CloseHandle ( m_sync );
        m_sync = NULL;
    }
}

void CSync::Lock () const
{
    WaitForSingleObject ( m_sync, INFINITE );
}

void CSync::UnLock () const
{
    ReleaseMutex ( m_sync );
}


CError::CError ( )
{

}

void CError::GetErrorString ( long lCode )
{
    char str[MAX_CONNECT_LEN];
    long nLen = 0;

    static const long lErrCodes[] =
    {
        WSAEACCES,
        WSAEADDRINUSE,
        WSAEADDRNOTAVAIL,
        WSAEAFNOSUPPORT,
        WSAEALREADY,
        WSAECONNABORTED,
        WSAECONNREFUSED,
        WSAECONNRESET,
        WSAEDESTADDRREQ,
        WSAEFAULT,
        WSAEHOSTDOWN,
        WSAEHOSTUNREACH,
        WSAEINPROGRESS,
        WSAEINTR,
        WSAEINVAL,
        WSAEISCONN,
        WSAEMFILE,
        WSAEMSGSIZE,
        WSAENETDOWN,
        WSAENETRESET,
        WSAENETUNREACH,
        WSAENOBUFS,
        WSAENOPROTOOPT,
        WSAENOTCONN,
        WSAENOTSOCK,
        WSAEOPNOTSUPP,
        WSAEPFNOSUPPORT,
        WSAEPROCLIM,
        WSAEPROTONOSUPPORT,
        WSAEPROTOTYPE,
        WSAESHUTDOWN,
        WSAESOCKTNOSUPPORT,
        WSAETIMEDOUT,
        WSAEWOULDBLOCK,
        WSAHOST_NOT_FOUND,
        WSANOTINITIALISED,
        WSANO_DATA,
        WSANO_RECOVERY,
        WSASYSNOTREADY,
        WSATRY_AGAIN,
        WSAVERNOTSUPPORTED,
        WSAEDISCON,
        1001,
        1002
    };

    static const char lpErrMsgs[][64] =
    {
        "Permission denied.",
        "Address already in use.",
        "Cannot assign requested address.",
        "Address family not supported by protocol family.",
        "Operation already in progress.",
        "Software caused connection abort.",
        "Connection refused.",
        "Connection reset by peer.",
        "Destination address required.",
        "Bad address.",
        "Host is down.",
        "No route to host.",
        "Operation now in progress.",
        "Interrupted function call.",
        "Invalid argument.",
        "Socket is already connected.",
        "Too many open sockets.",
        "Message too long.",
        "Network is down.",
        "Network dropped connection on reset.",
        "Network is unreachable.",
        "No buffer space available.",
        "Bad protocol option.",
        "Socket is not connected.",
        "Socket operation on nonsocket.",
        "Operation not supported.",
        "Protocol family not supported.",
        "Too many processes.",
        "Protocol not supported.",
        "Protocol wrong type for socket.",
        "Cannot send after socket shutdown.",
        "Socket type not supported.",
        "Connection timed out.",
        "Resource temporarily unavailable.",
        "Host not found.",
        "Successful WSAStartup not yet performed.",
        "Valid name, no data record of requested type.",
        "This is a nonrecoverable error.",
        "Network subsystem is unavailable.",
        "Nonauthoritative host not found.",
        "Winsock.dll version out of range.",
        "Graceful shutdown in progress."
        "Mutex not created.",
        "Thread not created."
    };

    for ( int i = 0; i < sizeof ( lErrCodes ) / sizeof ( long ); i++ )
    {
        if ( lCode == lErrCodes[i] )
        {
            int slen = strlen ( lpErrMsgs[i] );

            if ( nLen > slen + 1 ) nLen = slen + 1;

            if ( str ) memcpy ( str, lpErrMsgs[i], nLen );

        }
    }

    char lpUnknown[] = "Unknown error.";

    int slen = strlen ( lpUnknown );

    if ( nLen > slen + 1 ) nLen = slen + 1;

    if ( str ) memcpy ( str, lpUnknown, nLen );

//	TRACE(str);
}

⌨️ 快捷键说明

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