跨平台Socket封装——对IPv4地址的封装

来源:互联网 发布:java方法名长度 编辑:程序博客网 时间:2024/06/08 13:30

IPv4地址的封装主要是对sockadr_in的封装, 这是别人写的一个跨平台的代码,觉得不错,故记录下来。如果您看到代码,觉得还有改进的地方,可以说出来分享一下。
头文件SocketAddress.h

namespace LinWin{#define NET_DEFAULT_IP "0.0.0.0"class CSocketAddress{private:sockaddr_in m_addr;public:CSocketAddress(const char *ip = NET_DEFAULT_IP, unsigned short port = 0);CSocketAddress(const sockaddr_in &addr);CSocketAddress(const CSocketAddress &addr);CSocketAddress& operator=(const CSocketAddress &addr);virtual ~CSocketAddress();public:inline const struct sockaddr_in* GetAddress() const{   return &m_addr; }//添加一个非const版本的GetAddress函数inline struct sockaddr_in* GetAddress(){   return &m_addr; }inline void SetAddress(const struct sockaddr_in addr){   m_addr = addr;  }inline unsigned int AddressLength() const{   return sizeof(struct sockaddr_in);  }inline int GetFamily() const{   return m_addr.sin_family;   }inline void SetFamily(int fam){   m_addr.sin_family = fam;    }virtual unsigned int GetHost() const{   return m_addr.sin_addr.s_addr;  }inline void SetHost(unsigned int addr){   m_addr.sin_addr.s_addr = addr;  }inline unsigned short GetPort() const{   return m_addr.sin_port; }inline void SetPort(unsigned short p){   m_addr.sin_port = p;    }virtual int Parse(const std::string& addrStr);virtual int Parse(const std::string& addr, int port);virtual std::string ToString() const;};}

实现文件SocketAddress.cpp

LinWin::CSocketAddress::CSocketAddress(const char *ip, unsigned short port){    memset(&m_addr, 0, sizeof(sockaddr_in));    m_addr.sin_family = AF_INET;    m_addr.sin_addr.s_addr = inet_addr(ip);    m_addr.sin_port = htons(port);}LinWin::CSocketAddress::CSocketAddress(const struct sockaddr_in& addr) : m_addr(addr){}LinWin::CSocketAddress::CSocketAddress(const CSocketAddress& addr) : m_addr(addr.m_addr){}LinWin::CSocketAddress::~CSocketAddress(){}LinWin::CSocketAddress& LinWin::CSocketAddress::operator=(const CSocketAddress& addr){    if (&addr != this)    {        m_addr = addr.m_addr;    }    return *this;}std::string LinWin::CSocketAddress::ToString() const{    unsigned short port = ntohs(m_addr.sin_port);    std::string result = inet_ntoa(m_addr.sin_addr);    char buf[8];    sprintf(buf, ":%d", port);    result += buf;    return result;}int LinWin::CSocketAddress::Parse(const std::string& addrStr){    size_t i;    unsigned short port = 0;    size_t index = addrStr.find(":");    if (index == std::string::npos || (index + 1) == addrStr.length())        return -1;    const char* pData = addrStr.c_str();    i = 0;    while (isspace(pData[i]))        i++;    std::string tmp;    while (!isspace(pData[i]) && i < index)    {        tmp.push_back(pData[i]);        i++;    }    struct hostent *hostip = ::gethostbyname(tmp.c_str());    if (hostip == NULL)        return -1;    i = index + 1;    while (!isdigit(pData[i]) && i < addrStr.length())        i++;    port = atoi(pData + i);    memset(&m_addr, 0, sizeof(const struct sockaddr_in));    m_addr.sin_family = AF_INET;    memcpy((char*)&m_addr.sin_addr, hostip->h_addr, hostip->h_length);    m_addr.sin_port = htons(port);    return 0;}int LinWin::CSocketAddress::Parse(const std::string& addr, int port){    struct hostent *hostip = ::gethostbyname(addr.c_str());    if (hostip == NULL)        return -1;    memset(&m_addr, 0, sizeof(const struct sockaddr_in));    m_addr.sin_family = AF_INET;    memcpy((char*)&m_addr.sin_addr, hostip->h_addr, hostip->h_length);    m_addr.sin_port = htons(port);    return 0;}

命名空间是我自己添加的,如果不需要可以去掉。整体的代码是比较简单的,就是类的基础知识和socketaddr_in结构体的使用。类中留有两个接口,一个是解析像这样”域名 + 端口号”(如”www.baidu.com:80”)形式的接口;一个是输出”IP + 端口”(如”192.168.0.1:80”)这样的形式的接口。想要修改这两个接口,可以直接继承,在子类中重写这个接口。
新增一个接口,是把“域名”和“端口号”作为两个参数传入。

0 0
原创粉丝点击