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

📄 sockethandle.cpp

📁 利用UDP协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//      LPWSACOMPLETIONROUTINE lpCompletionRoutine: Completion routine
///////////////////////////////////////////////////////////////////////////////
DWORD CSocketHandle::ReadEx(LPBYTE lpBuffer, DWORD dwSize, LPSOCKADDR lpAddrIn,
                         LPWSAOVERLAPPED lpOverlapped, LPWSACOMPLETIONROUTINE lpCompletionRoutine)
{
    _ASSERTE( IsOpen() );
    _ASSERTE( lpBuffer != NULL );

    if (!IsOpen() || lpBuffer == NULL || dwSize < 1L)
        return (DWORD)-1L;

    SOCKET s = GetSocket();
    // Send message to peer
    WSABUF wsabuf;
    wsabuf.buf = (char FAR*)lpBuffer;
    wsabuf.len = dwSize;

    // Select function set read timeout
    DWORD dwBytesRead = 0L;
    DWORD dwFlags = 0L;
    int res = 0;
    if (lpAddrIn)
    {
        // UDP
        int fromlen = sizeof(SOCKADDR_IN);
        res = WSARecvFrom( s, &wsabuf, 1, &dwBytesRead, &dwFlags, lpAddrIn, &fromlen, lpOverlapped, lpCompletionRoutine);
    }
    else
    {
        // TCP
        res = WSARecv( s, &wsabuf, 1, &dwBytesRead, &dwFlags, lpOverlapped, lpCompletionRoutine);
    }
    if ( res == SOCKET_ERROR )
    {
        res = WSAGetLastError();
        if ( res != WSA_IO_PENDING )
        {
            dwBytesRead = -1L;
            SetLastError( res );
        }
    }

    return dwBytesRead;
}


///////////////////////////////////////////////////////////////////////////////
// Write
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//      Writes data to the Socket Communication
// PARAMETERS:
//      const LPBYTE lpBuffer: data to write
//      DWORD dwCount: maximum characters to write
//      LPSOCKADDR* lpAddrIn: socket address (UDP mode)
//      DWORD dwTimeout: timeout to use in millisecond
///////////////////////////////////////////////////////////////////////////////
DWORD CSocketHandle::Write(const LPBYTE lpBuffer, DWORD dwCount,
                          const LPSOCKADDR lpAddrIn, DWORD dwTimeout)
{
    _ASSERTE( IsOpen() );
    _ASSERTE( NULL != lpBuffer );

    // Accept 0 bytes message
    if (!IsOpen() || NULL == lpBuffer)
        return -1L;

    fd_set  fdWrite  = { 0 };
    TIMEVAL stTime;
    TIMEVAL *pstTime = NULL;

    if ( INFINITE != dwTimeout ) {
        stTime.tv_sec = dwTimeout/1000;
        stTime.tv_usec = (dwTimeout%1000)*1000;
        pstTime = &stTime;
    }

    SOCKET s = GetSocket();

    // Set Descriptor
    FD_SET( s, &fdWrite );

    // Select function set write timeout
    DWORD dwBytesWritten = 0L;
    int res = select((int)s, NULL, &fdWrite, NULL, pstTime );
    if ( res > 0)
    {
        // Send message to peer
        if (lpAddrIn)
        {
            // UDP
            res = sendto( s, (LPCSTR)lpBuffer, dwCount, 0, lpAddrIn, sizeof(SOCKADDR_IN));
        }
        else
        {
            // TCP
            res = send( s, (LPCSTR)lpBuffer, dwCount, 0);
        }
    }
    if ( res == SOCKET_ERROR )
    {
        SetLastError( WSAGetLastError() );
    }
    dwBytesWritten = (DWORD)((res >= 0)?(res) : (-1));

    return dwBytesWritten;
}


///////////////////////////////////////////////////////////////////////////////
// WriteEx
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//      Asynchronous Write to the Socket Communication
// PARAMETERS:
//      const LPBYTE lpBuffer: data to write
//      DWORD dwCount: maximum characters to write
//      LPSOCKADDR lpAddrIn: socket address (UDP mode)
//      LPWSAOVERLAPPED lpOverlapped: Overlapped structure
//      LPWSACOMPLETIONROUTINE lpCompletionRoutine: Completion routine
///////////////////////////////////////////////////////////////////////////////
DWORD CSocketHandle::WriteEx(const LPBYTE lpBuffer, DWORD dwCount,
                            const LPSOCKADDR lpAddrIn,
                            LPWSAOVERLAPPED lpOverlapped, LPWSACOMPLETIONROUTINE lpCompletionRoutine)
{
    _ASSERTE( IsOpen() );
    _ASSERTE( NULL != lpBuffer );

    // Accept 0 bytes message
    if (!IsOpen() || NULL == lpBuffer)
        return -1L;

    SOCKET s = GetSocket();

    // Select function set write timeout
    DWORD dwBytesWritten = 0L;
    int res = 0;
    // Send message to peer
    WSABUF wsabuf;
    wsabuf.buf = (char FAR*) lpBuffer;
    wsabuf.len = dwCount;
    if (lpAddrIn)
    {
        // UDP
        res = WSASendTo( s, &wsabuf, 1, &dwBytesWritten, 0, lpAddrIn, sizeof(SOCKADDR_IN),
            lpOverlapped, lpCompletionRoutine);
    }
    else // TCP
        res = WSASend( s, &wsabuf, 1, &dwBytesWritten, 0, lpOverlapped, lpCompletionRoutine);

    if ( res == SOCKET_ERROR )
    {
        res = WSAGetLastError();
        if ( res != WSA_IO_PENDING )
        {
            dwBytesWritten = -1L;
            SetLastError( res );
        }
    }

    return dwBytesWritten;
}

///////////////////////////////////////////////////////////////////////////////
// GetTransferOverlappedResult
///////////////////////////////////////////////////////////////////////////////
// DESCRIPTION:
//      Get overlapped result
// PARAMETERS:
//      LPWSAOVERLAPPED lpOverlapped: Overlapped structure
//      LPDWORD lpcbTransfer: Number of bytes tranferred
//      bool bWait: Force wait for the operation to complete
//      LPDWORD lpdwFlags: flags of the completion
///////////////////////////////////////////////////////////////////////////////
bool CSocketHandle::GetTransferOverlappedResult(LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer,
                                 bool bWait /*= true*/, LPDWORD lpdwFlags /*= NULL*/)
{
    _ASSERTE( IsOpen() );
    _ASSERTE( NULL != lpOverlapped );

    // Accept 0 bytes message
    if (!IsOpen() || NULL == lpOverlapped)
        return false;

    SOCKET s = GetSocket();
    DWORD dwFlags = 0;
    if ( lpdwFlags == NULL )
        lpdwFlags = &dwFlags;
    BOOL bRet = WSAGetOverlappedResult( s, lpOverlapped, lpcbTransfer, bWait, lpdwFlags );
    if ( !bRet )
    {
        SetLastError( WSAGetLastError() );
    }
    return (bRet != FALSE);
}


///////////////////////////////////////////////////////////////////////////////
// Utility functions

///////////////////////////////////////////////////////////////////////////////
// InitLibrary
bool CSocketHandle::InitLibrary(WORD wVersion)
{
    WSADATA WSAData = { 0 };
    return ( 0 == WSAStartup( wVersion, &WSAData ) );
}

///////////////////////////////////////////////////////////////////////////////
// ReleaseLibrary
bool CSocketHandle::ReleaseLibrary()
{
    return ( 0 == WSACleanup() ); 
}

///////////////////////////////////////////////////////////////////////////////
// WaitForConnection
SOCKET CSocketHandle::WaitForConnection(SOCKET sock)
{
    return accept(sock, 0, 0);
}

///////////////////////////////////////////////////////////////////////////////
// ShutdownConnection
bool CSocketHandle::ShutdownConnection(SOCKET sock)
{
    shutdown(sock, SD_BOTH);
    return ( 0 == closesocket( sock ));
}

static unsigned char chMinClassA_IP [] = { 1,   0,   0,   0   } ;
static unsigned char chMinClassD_IP [] = { 224, 0,   0,   0   } ;
static unsigned char chMaxClassD_IP [] = { 239, 255, 255, 255 } ;

///////////////////////////////////////////////////////////////////////////////
// IsUnicastIP
bool CSocketHandle::IsUnicastIP( ULONG ulAddr )
{
    return (((unsigned char *) & ulAddr) [0] >= chMinClassA_IP [0] &&
            ((unsigned char *) & ulAddr) [0] < chMinClassD_IP [0]) ;
}

///////////////////////////////////////////////////////////////////////////////
// IsMulticastIP
bool CSocketHandle::IsMulticastIP( ULONG ulAddr )
{
    return (((unsigned char *) & ulAddr) [0] >= chMinClassD_IP [0] &&
            ((unsigned char *) & ulAddr) [0] <= chMaxClassD_IP [0]) ;
}

///////////////////////////////////////////////////////////////////////////////
// FormatIP
bool CSocketHandle::FormatIP(LPTSTR pszIPAddr, UINT nSize, ULONG ulAddr, bool bFmtHost)
{
    if ( pszIPAddr )
    {
        if ( bFmtHost )
            ulAddr = htonl( ulAddr );
        // Create Address string
        return (SUCCEEDED(StringCchPrintf(pszIPAddr, nSize, _T("%u.%u.%u.%u"),
                            (UINT)(((PBYTE) &ulAddr)[0]),
                            (UINT)(((PBYTE) &ulAddr)[1]),
                            (UINT)(((PBYTE) &ulAddr)[2]),
                            (UINT)(((PBYTE) &ulAddr)[3]))));
    }
    return false;
}

///////////////////////////////////////////////////////////////////////////////
// GetPortNumber
USHORT CSocketHandle::GetPortNumber( LPCTSTR pszServiceName )
{
    LPSERVENT   lpservent;
    USHORT      nPort = 0;

    if ( _istdigit( pszServiceName[0] ) ) 
	{
        nPort = (USHORT) _ttoi( pszServiceName );
    }
    else {
#ifdef _UNICODE
        char pstrService[HOSTNAME_SIZE] = { 0 };
        WideCharToMultiByte(CP_ACP, 0, pszServiceName, -1, pstrService, sizeof(pstrService), NULL, NULL );
#else
        LPCTSTR pstrService = pszServiceName;
#endif
        // Convert network byte order to host byte order
        if ( (lpservent = getservbyname( pstrService, NULL )) != NULL )
            nPort = ntohs( lpservent->s_port );
    }

    return nPort;
}

///////////////////////////////////////////////////////////////////////////////
// GetIPAddress
ULONG CSocketHandle::GetIPAddress( LPCTSTR pszHostName )
{
    LPHOSTENT   lphostent;
    ULONG       uAddr = INADDR_NONE;
    TCHAR       szLocal[HOSTNAME_SIZE] = { 0 };

    // if no name specified, get local
    if ( NULL == pszHostName || !pszHostName[0])
    {
        GetLocalName(szLocal, HOSTNAME_SIZE);
        pszHostName = szLocal;
    }

#ifdef _UNICODE
    char pszHost[HOSTNAME_SIZE] = { 0 };
    WideCharToMultiByte(CP_ACP, 0, pszHostName, -1, pszHost, sizeof(pszHost), NULL, NULL );
#else
    LPCTSTR pszHost = pszHostName;
#endif

    // Check for an Internet Protocol dotted address string
    uAddr = inet_addr( pszHost );

    if ( (INADDR_NONE == uAddr) && (strcmp( pszHost, "255.255.255.255" )) )
    {
        // It's not an address, then try to resolve it as a hostname
        if ( (lphostent = gethostbyname( pszHost )) != NULL )
            uAddr = *((ULONG *) lphostent->h_addr_list[0]);
    }
    
    return ntohl( uAddr );
}

///////////////////////////////////////////////////////////////////////////////
// GetLocalName
bool CSocketHandle::GetLocalName(LPTSTR pszName, UINT nSize)
{
    if (pszName != NULL && nSize > 0)
    {
        char szHost[HOSTNAME_SIZE] = { 0 };

        // get host name, if fail, SetLastError is set
        if (SOCKET_ERROR != gethostname(szHost, sizeof(szHost)))
        {
            struct hostent* hp;
            hp = gethostbyname(szHost);
            if (hp != NULL) {
                ::StringCbCopyA(szHost, HOSTNAME_SIZE, hp->h_name);
            }

            // check if user provide enough buffer
            size_t cbLength = 0;
            ::StringCbLengthA(szHost, HOSTNAME_SIZE, &cbLength);
            if ( cbLength > nSize )
            {
                SetLastError(ERROR_INSUFFICIENT_BUFFER);
                return false;
            }

            // Unicode conversion
#ifdef _UNICODE
            return (0 != MultiByteToWideChar(CP_ACP, 0, szHost, -1, pszName, nSize ));
#else
            ::StringCbCopyA(pszName, nSize, szHost);
            return true;
#endif
        }
    }
    else
        SetLastError(ERROR_INVALID_PARAMETER);
    return false;
}

///////////////////////////////////////////////////////////////////////////////
// GetLocalAddress
bool CSocketHandle::GetLocalAddress(LPTSTR pszAddress, UINT nSize)
{
    // Get computer local address
    if (pszAddress != NULL && nSize > 0)
    {
        char szHost[HOSTNAME_SIZE] = { 0 };

        // get host name, if fail, SetLastError is called
        if (SOCKET_ERROR != gethostname(szHost, sizeof(szHost)))
        {
            struct hostent* hp;
            hp = gethostbyname(szHost);
            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
                szHost[0] = 0;

                // Create Address string
                ::StringCbPrintfA(szHost, HOSTNAME_SIZE, "%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
                size_t cbLength = 0;
                ::StringCbLengthA(szHost, HOSTNAME_SIZE, &cbLength);
                if ( cbLength > nSize)
                {
                    SetLastError(ERROR_INSUFFICIENT_BUFFER);
                    return false;
                }

                // Unicode conversion
#ifdef _UNICODE
                return (0 != MultiByteToWideChar(CP_ACP, 0, szHost, -1, pszAddress, nSize ));
#else
                ::StringCbCopyA(pszAddress, nSize, szHost);
                return true;
#endif
            }
        }
    }
    else
        SetLastError(ERROR_INVALID_PARAMETER);
    return false;
}

⌨️ 快捷键说明

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