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

📄 cconnection.cpp

📁 wince 下网络通讯类
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
* Copyright (c) 2009 xxx Electronics, Inc.
* All rights reserved.
*-----------------------------------------------------------------------------
* Description:
*     CConection     class  连接处理
*	  CError         class  错误处理
*     CNetworking    class  端口监听以及远程计算机信息获取
*     CSync          class  线程同步处理
*     CThreadManager class  线程创建、线程状态监控、线程释放
*	  CAcquisition   class  实时数据采集
*
* Change History:
*  04/26/2009          Chen Jian          添加注释规范代码、修正线程泄漏问题、添加错误处理
* Comments: 支持多个连接通讯
*
******************************************************************************/

#include "CConnection.h"

#define	BACKLOG				10			// 等待联接的最大队列长度
#define TIMEOUT				2			// sec
#define RECVSIZE			1024    // 接收缓存
#define MAX_CONNECT_LEN		512

long CNetworking::m_count = 0;

CNetworking::CNetworking () : m_lasterror ( )
{
    if ( m_count == 0 && CConnection::m_count == 0 )
    {
        WSADATA	wsd;
        int		err;

        err = WSAStartup ( MAKEWORD ( 1, 1 ), &wsd );

        if ( err != 0 )
            CError::GetErrorString ( err );
    }

    m_hAcceptEvent = NULL;

    m_hAcceptFunc = NULL;

    m_dwAcceptThreadID = 0;
    m_hAcceptThread = NULL;

    m_socket = INVALID_SOCKET;

    m_count ++;
}

CNetworking::~CNetworking ()
{
    StopListen ();

    if ( m_count == 1 && CConnection::m_count == 0 )
        WSACleanup();

    m_count --;
}



bool CNetworking::Listen ( int port )
{
    int flag = 1;
    int len = sizeof ( int );

    if ( IsListening () )
        StopListen ();

    sockaddr_in	addr;

    SOCKET		sock;

    sock = socket ( AF_INET, SOCK_STREAM, 0 );

    addr.sin_family = AF_INET;

    addr.sin_port = htons ( port );

    addr.sin_addr.s_addr = htonl ( INADDR_ANY );


    if ( bind ( sock, ( LPSOCKADDR ) &addr, sizeof ( addr ) ) == SOCKET_ERROR )
    {
        closesocket ( sock );
        long err = WSAGetLastError ();
        CError::GetErrorString ( err );
        return false;
    }

    if ( listen ( sock, BACKLOG ) < 0 )
    {
        closesocket ( sock );
        long err = WSAGetLastError ();
        CError::GetErrorString ( err );
        return false;
    }



    m_sync.Lock ();

    m_socket = sock;
    m_addr = addr;
    m_sync.UnLock ();


    m_hAcceptThread = CreateThread ( NULL,
                                     0,
                                     ( LPTHREAD_START_ROUTINE ) AcceptThread,
                                     this,
                                     0,
                                     ( LPDWORD ) & m_dwAcceptThreadID );

    if ( !m_hAcceptThread )
    {
        StopListen ();
        return false;
    }

    return true;
}

void CNetworking::StopListen ()
{
    if ( !IsListening () )
    {
        CError::GetErrorString ( WSAENOTCONN );
        return;
    }

    m_sync.Lock ();

    closesocket ( m_socket );
    m_socket = INVALID_SOCKET;
    m_sync.UnLock ();

    WaitForSingleObject ( m_hAcceptThread, INFINITE );

    CloseHandle ( m_hAcceptThread );
    m_hAcceptThread = NULL;
}

void CNetworking::SetAcceptFunc ( CALLBACKFUNC hFunc )
{
    m_sync.Lock ();
    m_hAcceptFunc = hFunc;
    m_sync.UnLock ();
}

void CNetworking::SetAcceptEvent ( HANDLE hEvent )
{
    m_sync.Lock ();
    m_hAcceptEvent = hEvent;
    m_sync.UnLock ();
}


CConnection* CNetworking::GetAccepted ()
{
    CConnection* cAccepted;

    m_sync.Lock ();
    cAccepted = m_accepted.Remove ();
    m_sync.UnLock ();

    return cAccepted;
}

int CNetworking::HasAccepted ()
{
    int iAccepted;

    m_sync.Lock ();
    iAccepted = m_accepted.Length ();
    m_sync.UnLock ();

    return iAccepted;
}

bool CNetworking::IsListening ()
{
    bool bListening;

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

    return bListening;
}

int CNetworking::AcceptWait ()
{
    int			addr_size = sizeof ( sockaddr_in );

    SOCKET		lsock;
    SOCKET		csock = INVALID_SOCKET;
    sockaddr_in	caddr = { 0 };

    m_sync.Lock ();
    lsock = m_socket;
    m_sync.UnLock ();

    while ( IsListening () )
    {
        m_sync.Lock ();
        bool bRightSock = ( lsock == m_socket );
        m_sync.UnLock ();

        if ( !bRightSock ) return 1;

        csock = accept ( lsock, ( LPSOCKADDR ) & caddr, &addr_size );

        if ( csock == INVALID_SOCKET )
        {
            int aErr = WSAGetLastError();

            if ( aErr == WSAEINTR )
            {
                StopListen ();
                return 1;
            }
            else
            {
                long err = WSAGetLastError ();
                CError::GetErrorString ( err );

                StopListen ();
                return 1;
            }
        }
        else
        {
            CConnection* cAccepted = new CConnection ();
            cAccepted->m_socket = csock;
            cAccepted->m_addr = caddr;

            cAccepted->m_hRecvThread = CreateThread ( NULL,
                                       0,
                                       ( LPTHREAD_START_ROUTINE ) cAccepted->RecvThread,
                                       cAccepted,
                                       0,
                                       ( LPDWORD ) & cAccepted->m_dwRecvThreadID );

            if ( cAccepted->m_hRecvThread == NULL )
            {
                //cAccepted->Disconnect ();
                delete cAccepted;
                CError::GetErrorString ( 1002 );
            }
            else
            {
                m_sync.Lock ();
                m_accepted.Add ( cAccepted );

                HANDLE hEvent = m_hAcceptEvent;
                CALLBACKFUNC fncCallback = m_hAcceptFunc;
                m_sync.UnLock ();

                if ( hEvent ) SetEvent ( hEvent );

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

    return 0;
}

int CNetworking::AcceptThread ( void* pThis )
{
    return ( ( CNetworking* ) ( pThis ) )->AcceptWait ();
}


bool CNetworking::GetLocalName ( char *localname, int len )
{
    char locname[512] = "";

    int status = gethostname ( locname, 512 );

    if ( status != 0 )
    {
        long err = WSAGetLastError ();
        CError::GetErrorString ( err );
        return false;
    }

    memset ( localname, 0, len );

    int uselen = strlen ( locname ) + 1;

    if ( uselen > len ) uselen = len;

    memcpy ( localname, locname, uselen );

    return true;
}

bool CNetworking::GetLocalIP ( char *localip, int len )
{
    char locname[512];
    char locip[16];

    if ( ! ( GetLocalName ( locname, 512 ) && ResolveIP ( locname, locip, 16 ) ) )
        return false;


    memset ( localip, 0, len );

    int uselen = strlen ( locip ) + 1;

    if ( len < uselen ) uselen = len;

    memcpy ( localip, locip, uselen );

    return true;
}

bool CNetworking::GetLocalIPs ( char *localips, int len )
{
    char locname[512] = "";
    char locips[256] = "";

    if ( !GetLocalName ( locname, 512 ) || !ResolveIPs ( locname, locips, 256 ) )
        return false;

    memset ( localips, 0, len );

    int uselen = strlen ( locips ) + 1;

    if ( len < uselen ) uselen = len;

    memcpy ( localips, locips, uselen );

    return true;
}

bool CNetworking::ResolveName ( char *hostip, char *hostname, int len )
{
    unsigned long hstaddr = inet_addr ( hostip );
    hostent* phe = gethostbyaddr ( ( char* ) & hstaddr, sizeof ( unsigned long ), AF_INET );

    if ( phe == NULL )
    {
        long err = WSAGetLastError ();
        CError::GetErrorString ( err );
        return false;
    }

    char *hstname = ( char* ) phe->h_name;

    memset ( hostname, 0, len );

    int uselen = strlen ( hstname ) + 1;

    if ( len < uselen ) uselen = len;

    memcpy ( hostname, hstname, uselen );

    return true;
}

bool CNetworking::ResolveIP ( char *hostname, char *hostip, int len )
{
    hostent* phe = gethostbyname ( hostname );

    if ( phe == NULL )
    {
        long err = WSAGetLastError ();
        CError::GetErrorString ( err );
        return false;
    }

    char hstip[15] = "";

    if ( phe->h_addr_list[0] != NULL )
    {
        sprintf ( hstip, "%u.%u.%u.%u",
                  ( unsigned char ) phe->h_addr_list[0][0],
                  ( unsigned char ) phe->h_addr_list[0][1],
                  ( unsigned char ) phe->h_addr_list[0][2],
                  ( unsigned char ) phe->h_addr_list[0][3] );
    }
    else
    {
        long err = WSAGetLastError ();
        CError::GetErrorString ( err );
        return false;
    }

    memset ( hostip, 0, len );

    int uselen = strlen ( hstip ) + 1;

    if ( len < uselen ) uselen = len;

    memcpy ( hostip, hstip, uselen );

    return true;
}

bool CNetworking::ResolveIPs ( char *hostname, char *hostips, int len )
{
    hostent *phe = gethostbyname ( hostname );
    char	allips[256], null_ip[256];

    if ( phe == NULL || phe->h_addr_list[0] == NULL )
    {
        long err = WSAGetLastError ();
        CError::GetErrorString ( err );
        return false;
    }

    int count = 0,

                i = 0;

    for ( i = 0; i < 256; i++ )
    {
        allips[i] = 0;
        null_ip[i] = 0;
    }

    while ( phe->h_addr_list[count] != NULL && count * 15 < 240 )
    {
        char oneip[15] = "";

        for ( i = 0; i < 15; i++ )
            oneip[i] = 0;

        sprintf ( oneip, "%u.%u.%u.%u",
                  ( unsigned char ) phe->h_addr_list[count][0],
                  ( unsigned char ) phe->h_addr_list[count][1],
                  ( unsigned char ) phe->h_addr_list[count][2],
                  ( unsigned char ) phe->h_addr_list[count][3] );

        for ( i = ( count * 15 ); i < ( count * 15 + 15 ); i++ )
            null_ip[i] = oneip[i % 15];

        count++;
    }

    int lEnd = 0;

    for ( i = 0; i < 15; i++ )
    {
        if ( null_ip[i * 15] == 0 ) break;

        for ( int j = 0; j < 15; j++ )
            allips[lEnd + j] = null_ip[i * 15 + j];

        lEnd = strlen ( allips );

        allips[lEnd] = 13;

        lEnd ++;
    }

    for ( i = 0; i < len; i++ )
        hostips[i] = 0;

    int uselen = strlen ( allips );

    if ( uselen > len ) uselen = len;

    for ( i = 0; i < uselen; i++ )
        hostips[i] = allips[i];

    hostips[uselen] = 0;

    return true;
}




long CConnection::m_count = 0;

CConnection::CConnection ()
{
    if ( m_count == 0 && CNetworking::m_count == 0 )
    {
        WSADATA	wsd;
        int		err;

        err = WSAStartup ( MAKEWORD ( 1, 1 ), &wsd );

        if ( err != 0 )
            CError::GetErrorString ( err );
    }


    m_event = CreateEvent ( NULL, TRUE, FALSE, NULL );

    m_hCloseEvent = NULL;
    m_hCloseFunc = NULL;
    m_hRecvEvent = NULL;
    m_hRecvFunc = NULL;

    m_dwRecvThreadID = 0;
    m_hRecvThread = NULL;

    m_socket = INVALID_SOCKET;

    m_count ++;
}

CConnection::CConnection ( const char* host, unsigned short port )
{
    if ( m_count == 0 && CNetworking::m_count == 0 )
    {
        WSADATA	wsd;
        int		err;

        err = WSAStartup ( MAKEWORD ( 1, 1 ), &wsd );

        if ( err != 0 )
            CError::GetErrorString ( err );
    }

    m_event = CreateEvent ( NULL, TRUE, FALSE, NULL );

    m_hCloseEvent = NULL;
    m_hCloseFunc = NULL;
    m_hRecvEvent = NULL;
    m_hRecvFunc = NULL;

    m_dwRecvThreadID = 0;
    m_hRecvThread = NULL;

    m_socket = INVALID_SOCKET;

    m_count ++;

    if ( !Connect ( host, port ) )
    {
        long err = WSAGetLastError ();

        if ( err == 0 )
            CError::GetErrorString ( err );
    }
}

CConnection::~CConnection ()
{
    Disconnect ();

    if ( m_count == 1 && CNetworking::m_count == 0 )
        WSACleanup();

    CloseHandle ( m_event );

    m_count --;
}


bool CConnection::Connect ( const char* host, unsigned short port )
{
    Disconnect ();

    sockaddr_in	addr;
    SOCKET		sock;

    sock = socket ( AF_INET, SOCK_STREAM, 0 );
    addr.sin_family = AF_INET;
    addr.sin_port = htons ( port );
    addr.sin_addr.s_addr = inet_addr ( host );

    if ( connect ( sock, ( LPSOCKADDR ) &addr, sizeof ( addr ) ) == SOCKET_ERROR )
    {
        long err = WSAGetLastError ();
        CError::GetErrorString ( err );
        return false;
    }

    linger lg;

    lg.l_onoff = 1;
    lg.l_linger = 10;
    setsockopt ( sock, SOL_SOCKET, SO_LINGER, reinterpret_cast <const char*> ( &lg ), sizeof ( linger ) );

    m_hRecvThread = CreateThread ( NULL,
                                   0,
                                   ( LPTHREAD_START_ROUTINE ) RecvThread,
                                   this,
                                   0,
                                   ( LPDWORD ) & m_dwRecvThreadID );

    if ( m_hRecvThread == NULL )
    {
        CError::GetErrorString ( 1002 );
        closesocket ( sock );
        return false;
    }

    m_sync.Lock ();

    m_socket = sock;
    m_addr = addr;
    m_sync.UnLock ();

    return true;
}

void CConnection::Disconnect ()
{
    if ( !IsConnected () )
    {
        CError::GetErrorString ( WSAENOTCONN );
        return;
    }

    int		status;

    fd_set	readfds;

⌨️ 快捷键说明

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