Design to simplify the original tutorial - Communication - socket CxSocket

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

  This is a concise socket classes, class, function and variable names are used in Hungarian notation. Lowercase x to represent my initials (Xie Xinneng), personal habits, if identical, is purely coincidental.

CxSocket is defined as follows:

#include <winsock2.h>

#define    MAX_IPV6          64

#pragma pack(1)

typedef struct tagIPADDR_PORT
{
    char szAddr[MAX_IPV6];
    int nPort;
}
IPADDR_PORT, *PIPADDR_PORT;

#pragma pack()


class XIOCTRL_CLASS CxSocket
{
public:
    CxSocket();
    virtual ~CxSocket();

    void operator=(SOCKET s) { m_socket = s; }
    void Attach(SOCKET s) { m_socket = s; }

public:
    static BOOL Init();
    static BOOL UnInit();

    static void MacStringToAddress(LPCSTR lpszMac, PULONGLONG pullAddr);
    static void MacAddressToString(const PULONGLONG pullAddr, LPSTR lpszMac);
    static BOOL GetLocalHost(LPSTR lpszIPAddr);
    static DWORD WSAGetLastError();

    void SetWindowMessage(MSG* pMsg, WNDPROC wndproc = NULL)
    {
        m_msg = *pMsg;
        m_wndproc = wndproc;
    }

    SOCKET GetSocket() { return m_socket; }
    BOOL SelectEvent(long lEvent);

protected:
    MSG    m_msg;
    WNDPROC m_wndproc;
    SOCKET m_socket;
};

  Because this class is encapsulated in a dynamic library, so the class name before using the derived markers XIOCTRL_CLASS, readers can be removed completely when in use. Class definitions are placed in a contains many classes defined in the header file, not alone for it to write the header file, so it's defined part of the code looks no context.

  The implementation of CxSocket is as follows:

// xSocket.cpp: implementation of the CxSocket class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "../xIOCtrl.h"

#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CxSocket::CxSocket()
: m_wndproc(NULL)
, m_socket(INVALID_SOCKET)
{
    ZeroMemory(&m_msg, sizeof(m_msg));
}

CxSocket::~CxSocket()
{

}

BOOL CxSocket::Init()
{
    WSADATA wsaData;
    WORD wVersionRequested = MAKEWORD(2, 2);
    
    if (WSAStartup(wVersionRequested, &wsaData) != 0)
        return FALSE;
    
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
    {
        WSACleanup();
        return FALSE;
    }

    return TRUE;
}

BOOL CxSocket::UnInit()
{
    if (WSACleanup() != 0)
        return FALSE;

    return TRUE;
}

void CxSocket::MacStringToAddress(LPCSTR lpszMac, PULONGLONG pullAddr)
{
    *pullAddr = 0;
    LPBYTE lpbtAddr = (LPBYTE)pullAddr;
    DWORD dwAddr[6];
    sscanf(lpszMac, "%02x:%02x:%02x:%02x:%02x:%02x",
            &dwAddr[5], &dwAddr[4], &dwAddr[3],
            &dwAddr[2], &dwAddr[1], &dwAddr[0]);

    for (int i=0; i<6; i++)
        lpbtAddr[i] = (BYTE)dwAddr[i];
}

void CxSocket::MacAddressToString(const PULONGLONG pullAddr, LPSTR lpszMac)
{
    LPBYTE lpbtAddr = (LPBYTE)pullAddr;
    sprintf(lpszMac, "%02x:%02x:%02x:%02x:%02x:%02x",
            lpbtAddr[5], lpbtAddr[4], lpbtAddr[3],
            lpbtAddr[2], lpbtAddr[1], lpbtAddr[0]);
}

BOOL CxSocket::GetLocalHost(LPSTR lpszIPAddr)
{
    char szName[MAX_PATH] = {'\0'};
    gethostname(szName, sizeof(szName));
    struct hostent * phe = gethostbyname(szName);
    if (phe == NULL)
        return FALSE;
    
    if (phe->h_addr_list[0] == 0)
        return FALSE;
    
    in_addr ia;
    memcpy(&ia, phe->h_addr_list[0], sizeof(struct in_addr));
    if ((ia.s_net == 127) ||
        (ia.s_net == 169) ||
        (ia.s_net == 255))
        return FALSE;

    strcpy(lpszIPAddr, inet_ntoa(ia));
    return TRUE;
}

DWORD CxSocket::WSAGetLastError()
{ 
    return ::WSAGetLastError();
}

BOOL CxSocket::SelectEvent(long lEvent)
{
    int nRet = WSAAsyncSelect(m_socket, m_msg.hwnd,
                                m_msg.message, lEvent);
    return (nRet != SOCKET_ERROR);
}

  This class is a bit like the inside of the MFC CWnd as a base class for all kinds of window class exists, it serves as a base class for various socket type exists. In addition to the static functions of some convenient and can be used directly, does not recommend the instantiation, because the member function almost no (various socket classes inherit from it has more functions, the future of the article will introduce).

  Concise code does not need to explain, you know. To be continued...

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Rudolf at November 18, 2013 - 2:19 PM