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

📄 socketcomm.cpp

📁 Multi-threaded Client/Server Socket Class
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        if (SOCKET_ERROR != gethostname(strHost, sizeof(strHost)))
        {
            struct hostent* hp;
            hp = gethostbyname(strHost);
            if (hp != NULL && hp->h_addr_list[0] != NULL)
            {
                // IPv4: Address is four bytes (32-bit)
                if ( hp->h_length < 4)
                    return false;

                // Convert address to . format
                strHost[0] = 0;

                // IPv4: Create Address string
                sprintf(strHost, "%u.%u.%u.%u",
                    (UINT)(((PBYTE) hp->h_addr_list[0])[0]),
                    (UINT)(((PBYTE) hp->h_addr_list[0])[1]),
                    (UINT)(((PBYTE) hp->h_addr_list[0])[2]),
                    (UINT)(((PBYTE) hp->h_addr_list[0])[3]));

                // check if user provide enough buffer
                if (strlen(strHost) > nSize)
                {
                    SetLastError(ERROR_INSUFFICIENT_BUFFER);
                    return false;
                }

            // Unicode conversion
#ifdef _UNICODE
                return (0 != MultiByteToWideChar(CP_ACP, 0, strHost, -1, strAddress,nSize ));
#else
                _tcscpy(strAddress, strHost);
                return true;
#endif
            }
        }
    }
    else
        SetLastError(ERROR_INVALID_PARAMETER);
    return false;
}


///////////////////////////////////////////////////////////////////////////////
// WaitForConnection
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//              Wait for a network connection.  Only for connection type of socket
//              This function may fail, in this case it returns "INVALID_SOCKET"
// PARAMETERS:
//  SOCKET sock: a socket capable of receiving new connection (TCP: SOCK_STREAM)
///////////////////////////////////////////////////////////////////////////////
SOCKET CSocketComm::WaitForConnection(SOCKET sock)
{
    // Accept an incoming connection - blocking
    // no information about remote address is returned
    return accept(sock, 0, 0);
}


///////////////////////////////////////////////////////////////////////////////
// ShutdownConnection
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//              Shutdown a connection and close socket.  This will force all
//              transmission/reception to fail.
// PARAMETERS:
//  SOCKET sock: Socket to close
///////////////////////////////////////////////////////////////////////////////
bool CSocketComm::ShutdownConnection(SOCKET sock)
{
    shutdown(sock, SD_BOTH);
    return ( 0 == closesocket( sock ));
}


///////////////////////////////////////////////////////////////////////////////
// GetSockName
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//              retrieves the local name for a socket
// PARAMETERS:
//  SockAddrIn& saddr_in: object to store address
///////////////////////////////////////////////////////////////////////////////
bool CSocketComm::GetSockName(SockAddrIn& saddr_in)
{
    if (IsOpen())
    {
        int namelen = saddr_in.Size();
        return (SOCKET_ERROR != getsockname(GetSocket(), saddr_in, &namelen));
    }

    return false;
}


///////////////////////////////////////////////////////////////////////////////
// GetPeerName
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//              retrieves the name of the peer to which a socket is connected
// PARAMETERS:
//  SockAddrIn& saddr_in: object to store address
///////////////////////////////////////////////////////////////////////////////
bool CSocketComm::GetPeerName(SockAddrIn& saddr_in)
{
    if (IsOpen())
    {
        int namelen = saddr_in.Size();
        return (SOCKET_ERROR != getpeername(GetSocket(), saddr_in, &namelen));  
    }

    return false;
}

///////////////////////////////////////////////////////////////////////////////
// AddMembership
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//              Add membership to a multicast address
// PARAMETERS:
//  LPCTSTR strAddress: ip address for membership
///////////////////////////////////////////////////////////////////////////////
bool CSocketComm::AddMembership(LPCTSTR strAddress)
{
    if ( IsOpen() )
    {
        int nType = 0;
        int nOptLen = sizeof(int);
        SOCKET sock = (SOCKET) m_hComm;
        if ( SOCKET_ERROR != getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&nType, &nOptLen))
        {
            if ( nType == SOCK_DGRAM )
            {
                int nTTL = 5;
                if ( SOCKET_ERROR != setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&nTTL, sizeof(nTTL)))
                {
                    ip_mreq mreq;
                    mreq.imr_multiaddr.s_addr = htonl( CSocketComm::GetIPAddress( strAddress ) );
                    mreq.imr_interface.s_addr = htonl( INADDR_ANY );
                    return ( SOCKET_ERROR != setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)));
                }
            }
        }
    }
    return false;
}


///////////////////////////////////////////////////////////////////////////////
// DropMembership
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//              Remove membership from a multicast address
// PARAMETERS:
//  LPCTSTR strAddress: ip address for membership
///////////////////////////////////////////////////////////////////////////////
bool CSocketComm::DropMembership(LPCTSTR strAddress)
{
    if ( IsOpen() )
    {
        int nType = 0;
        int nOptLen = sizeof(int);
        SOCKET sock = (SOCKET) m_hComm;
        if ( SOCKET_ERROR != getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&nType, &nOptLen))
        {
            if ( nType == SOCK_DGRAM )
            {
                ip_mreq mreq;
                mreq.imr_multiaddr.s_addr = htonl( CSocketComm::GetIPAddress( strAddress ) );
                mreq.imr_interface.s_addr = htonl( INADDR_ANY );
                return ( SOCKET_ERROR != setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)));
            }
        }
    }
    return false;
}


///////////////////////////////////////////////////////////////////////////////
// CreateSocketEx
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//              This function creates a new socket for connection (SOCK_STREAM)
//              or an connectionless socket (SOCK_DGRAM).  A connectionless
//              socket should not call "accept()" since it cannot receive new
//              connection.  This is used as SERVER socket
// PARAMETERS:
//  LPCTSTR strHost: Hostname or adapter IP address
//  LPCTSTR strServiceName: Service name or port number
//  int nFamily: address family to use (set to AF_INET)
//  int nType: type of socket to create (SOCK_STREAM, SOCK_DGRAM)
//  UINT uOptions: other options to use
///////////////////////////////////////////////////////////////////////////////
bool CSocketComm::CreateSocketEx(LPCTSTR strHost, LPCTSTR strServiceName, int nFamily, int nType, UINT uOptions /* = 0 */)
{
    // Socket is already opened
    if ( IsOpen() )
        return false;

    // Create a Socket that is bound to a specific service provide
    // nFamily: (AF_INET)
    // nType: (SOCK_STREAM, SOCK_DGRAM)
    SOCKET sock = socket(nFamily, nType, IPPROTO_IP);
    if (INVALID_SOCKET != sock)
    {
        if (uOptions & SO_REUSEADDR)
        {
            // Inform Windows Sockets provider that a bind on a socket should not be disallowed
            // because the desired address is already in use by another socket
            BOOL optval = TRUE;
            if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof( BOOL ) ) )
            {
                closesocket( sock );
                return false;
            }
        }

        if (nType == SOCK_DGRAM)
        {
            if (uOptions & SO_BROADCAST)
            {
                // Inform Windows Sockets provider that broadcast messages are allowed
                BOOL optval = TRUE;
                if ( SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_BROADCAST, (char *) &optval, sizeof( BOOL ) ) )
                {
                    closesocket( sock );
                    return false;
                }
            }
        }

        // Associate a local address with the socket
        SockAddrIn sockAddr;
        sockAddr.CreateFrom(strHost, strServiceName, nFamily);

        if ( SOCKET_ERROR == bind(sock, sockAddr, sockAddr.Size()))
        {
            closesocket( sock );
            return false;
        }

        // Listen to the socket, only valid for connection socket
        if (SOCK_STREAM == nType)
        {
            if ( SOCKET_ERROR == listen(sock, SOMAXCONN))
            {
                closesocket( sock );
                return false;
            }
        }

        // Success, now we may save this socket
        m_hComm = (HANDLE) sock;
    }

    return (INVALID_SOCKET != sock);
}

///////////////////////////////////////////////////////////////////////////////
// CreateSocket
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//              This function creates a new socket for connection (SOCK_STREAM)
//              or an connectionless socket (SOCK_DGRAM).  A connectionless
//              socket should not call "accept()" since it cannot receive new
//              connection.  This is used as SERVER socket
// PARAMETERS:
//  LPCTSTR strServiceName: Service name or port number
//  int nFamily: address family to use (set to AF_INET)
//  int nType: type of socket to create (SOCK_STREAM, SOCK_DGRAM)
//  UINT uOptions: other options to use
///////////////////////////////////////////////////////////////////////////////
bool CSocketComm::CreateSocket(LPCTSTR strServiceName, int nFamily, int nType, UINT uOptions /* = 0 */)
{
    return CreateSocketEx(NULL, strServiceName, nFamily, nType, uOptions);
}


///////////////////////////////////////////////////////////////////////////////
// ConnectTo
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//              Establish connection with a server service or port
// PARAMETERS:
//  LPCTSTR strDestination: hostname or address to connect (in .dot format)
//  LPCTSTR strServiceName: Service name or port number
//  int nFamily: address family to use (set to AF_INET)
//  int nType: type of socket to create (SOCK_STREAM, SOCK_DGRAM)
///////////////////////////////////////////////////////////////////////////////
bool CSocketComm::ConnectTo(LPCTSTR strDestination, LPCTSTR strServiceName, int nFamily, int nType)
{
    // Socket is already opened
    if ( IsOpen() )
        return false;

    // Create a Socket that is bound to a specific service provide
    // nFamily: (AF_INET)
    // nType: (SOCK_STREAM, SOCK_DGRAM)
    SOCKET sock = socket(nFamily, nType, 0);
    if (INVALID_SOCKET != sock)
    {
        // Associate a local address with the socket
        SockAddrIn sockAddr;
        if (false == sockAddr.CreateFrom(NULL, TEXT("0"), nFamily))
        {
            closesocket( sock );
            return false;
        }

        if ( SOCKET_ERROR == bind(sock, sockAddr, sockAddr.Size() ))
        {
            closesocket( sock );
            return false;
        }

        // Now get destination address & port
        sockAddr.CreateFrom( strDestination, strServiceName );

        // try to connect - if fail, server not ready
        if (SOCKET_ERROR == connect( sock, sockAddr, sockAddr.Size()))
        {
            closesocket( sock );
            return false;
        }

        // Success, now we may save this socket
        m_hComm = (HANDLE) sock;
    }
    return (INVALID_SOCKET != sock);
}


///////////////////////////////////////////////////////////////////////////////
// CloseComm
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//      Close Socket Communication
// PARAMETERS:
//      None
///////////////////////////////////////////////////////////////////////////////
void CSocketComm::CloseComm()
{
    if (IsOpen())
    {
        ShutdownConnection((SOCKET)m_hComm);
        m_hComm = INVALID_HANDLE_VALUE;
        m_bBroadcast = false;
    }
}


///////////////////////////////////////////////////////////////////////////////
// WatchComm
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//      Starts Socket Communication Working thread
// PARAMETERS:
//      None
///////////////////////////////////////////////////////////////////////////////
bool CSocketComm::WatchComm()
{
    if (!IsStart())
    {
        if (IsOpen())
        {
            HANDLE hThread;
            UINT uiThreadId = 0;

⌨️ 快捷键说明

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