in_addr,char* ,unsigned long 之间的互相转换

       在网络编程中经常会用到in_addr,char* ,unsigned long表示的IP地址(指定的是IP4),winsock 提供inet_addr(char* -> unsigned  long),inet_ntoa(in_addr -> char*),在实际应用中,不同数据类型总是需要转换,如果每一次转换需要调用函数转换,这样会很繁琐。

      通常,一个IP(v4)地址是一个32位无符号的整数类型,即unsigned long,而in_addr结构可以用来表现每个8位的数值(u_char),in_addr结构实际上也是一个32位无符号的整数类型,也就是in_addr::S_un::S_addr,这样in_addr可以和unsigned long直接转换。为了便于阅读,并提供了char*的形式来表示ip地址。inet_addr用于从 char* 类型到  unsigned  long的转换;inet_ntoa提供了从in_addr -> char*的转换。

     虽然 in_addr,char* ,unsigned long之间可以通过函数来转换,但编写代码的过程很繁琐,几乎每一次转换调用都需要调用函数,而且很容易忘记函数。既然这几个类型可以互相转换,那就可以通过一个类来封装这些类型,使得这些类型可以在类的封装下实现互相转换。

   下面使用一个命名为CIPv4AddressForm的类封装上述的三种数据类型,并在类实现几个常用的方法,比如得到数据成员的数值、在不同类型之间直接转换(实现运算符重载),不同数据类型之间直接赋值。

//定义

 class CIPv4AddressForm{
  protected:
  char*              m_pc;
  in_addr           m_addr;
  unsigned long  m_ul;
  public:
  inline CIPv4AddressForm(){}
  CIPv4AddressForm(char*  IpAddress);
  CIPv4AddressForm(unsigned long& IpAddress);
  CIPv4AddressForm(in_addr  IpAddress);
  CIPv4AddressForm(CIPv4AddressForm& ins);
  virtual ~CIPv4AddressForm();
  /*重新设置*/
  CIPv4AddressForm& Reset(char*  IpAddress);
  CIPv4AddressForm& Reset(unsigned long& IpAddress);
  CIPv4AddressForm& Reset(in_addr  IpAddress);
  
  /*获取类型*/
  char* ToString()const;
  unsigned long ToUInt() ;
  in_addr& ToAddr();
  /*自动转换*/
  operator unsigned long();
  operator char* ()const;
  operator in_addr& ();
  /*比较是否相等*/
 bool operator ==(CIPv4AddressForm& r );
 bool operator ==(char* r);
 bool operator ==(in_addr& r);
 bool operator ==(unsigned long& r);

 bool operator !=(CIPv4AddressForm& r);
 bool operator !=(char* r);
 bool operator !=(in_addr& r);
 bool operator !=(unsigned long& r);
 /*赋值*/
 CIPv4AddressForm& operator =(CIPv4AddressForm& r);
 CIPv4AddressForm& operator =(char* r);
 CIPv4AddressForm& operator =(unsigned long& r);
 CIPv4AddressForm& operator =(in_addr& r);
  };


//实现

  CIPv4AddressForm::CIPv4AddressForm(in_addr IpAddress){
	   this->m_addr=IpAddress;
	   this->m_ul=this->m_addr.S_un.S_addr;
	   this->m_pc=inet_ntoa(this->m_addr);
   }
   CIPv4AddressForm::CIPv4AddressForm(unsigned long& IpAddress){
	   this->m_ul=IpAddress;
	   this->m_addr.S_un.S_addr=IpAddress;
       this->m_pc=inet_ntoa(this->m_addr);
   }
   CIPv4AddressForm::CIPv4AddressForm(char* IpAddress){
	   this->m_ul=inet_addr(IpAddress);
	   this->m_addr.S_un.S_addr=this->m_ul;
	   this->m_pc=inet_ntoa(this->m_addr);//不要直接 this->m_pc=IpAddress,否则IpAddress释放了m_pc就没作用了
   }


   CIPv4AddressForm::CIPv4AddressForm(CIPv4AddressForm& ins){
	   this->m_ul=ins.ToUInt();
	   this->m_addr.S_un.S_addr=this->m_ul;
	   this->m_pc=inet_ntoa(this->m_addr);
   }


   CIPv4AddressForm::~CIPv4AddressForm(){
	   //no implement...
   }
  /*重新设置*/
   CIPv4AddressForm& CIPv4AddressForm::Reset(in_addr IpAddress){
	   this->m_addr=IpAddress;
	   this->m_ul=this->m_addr.S_un.S_addr;
	   this->m_pc=inet_ntoa(this->m_addr);
	   return (*this);
   }
   CIPv4AddressForm& CIPv4AddressForm::Reset(unsigned long& IpAddress){
	   this->m_ul=IpAddress;
	   this->m_addr.S_un.S_addr=IpAddress;
	   this->m_pc=inet_ntoa(this->m_addr);
	   return (*this);
   }
   CIPv4AddressForm& CIPv4AddressForm::Reset(char* IpAddress){
	   this->m_ul=inet_addr(IpAddress);
	   this->m_addr.S_un.S_addr=this->m_ul;
	   this->m_pc=inet_ntoa(this->m_addr);//不要直接 this->m_pc=IpAddress
	   return (*this);
   }
   /*获取类型*/
   char* CIPv4AddressForm::ToString()const{
       return this->m_pc;
   }
   unsigned long CIPv4AddressForm::ToUInt(){
	   return this->m_ul;
   }
   in_addr& CIPv4AddressForm::ToAddr(){
	   return this->m_addr;
   }
  /*自动转换*/
   CIPv4AddressForm::operator unsigned long(){
	   return this->m_ul;
   }
   CIPv4AddressForm::operator char *()const{
	   return this->m_pc;
   }
   CIPv4AddressForm::operator in_addr &(){
	   return this->m_addr;
   }
     /*比较是否相等*/
   bool CIPv4AddressForm::operator ==(CIPv4AddressForm &r){
	   if(this->m_ul==r.ToUInt()) return true;
	   return false;
   }


   bool CIPv4AddressForm::operator ==(char* r){
	   if(lstrcmpiA(r,this->m_pc)==0) return true; 
	   return false;
   }


   bool CIPv4AddressForm::operator ==(unsigned long& r){
	  if(this->m_ul==r) return true;
	   return false;
   }
   bool CIPv4AddressForm::operator ==(in_addr &r){
	   if(this->m_addr.S_un.S_addr==r.S_un.S_addr) return true;
	   return false;
   }


   bool CIPv4AddressForm::operator !=(CIPv4AddressForm &r){
	   if(this->m_ul!=r.ToUInt()) return true;
	   return false;
   }
   bool CIPv4AddressForm::operator !=(char* r){
	 if(lstrcmpiA(r,this->m_pc)!=0) return true; 
	   return false;
   }
   bool CIPv4AddressForm::operator !=(unsigned long& r){
	  if( this->m_ul!=r) return true;
	   return false;
   }
   bool CIPv4AddressForm::operator !=(in_addr &r){
	   if(this->m_addr.S_un.S_addr!=r.S_un.S_addr) return true;
	   return false;
   }
/*赋值*/
   CIPv4AddressForm& CIPv4AddressForm::operator =(CIPv4AddressForm& r){
	   this->m_ul=r.ToUInt();
	   this->m_addr.S_un.S_addr=this->m_ul;
	   this->m_pc=inet_ntoa(this->m_addr);
	   return (*this);
   }
   CIPv4AddressForm& CIPv4AddressForm::operator =(char* r){
	   this->m_ul=inet_addr(r);
	   this->m_addr.S_un.S_addr=this->m_ul;
	   this->m_pc=inet_ntoa(this->m_addr);
	   return (*this);
   }
   CIPv4AddressForm& CIPv4AddressForm::operator =(unsigned long & r){
	   this->m_ul=r;
	   this->m_addr.S_un.S_addr=r;
	   this->m_pc=inet_ntoa(this->m_addr);
	   return(*this);
   }
   CIPv4AddressForm& CIPv4AddressForm::operator =(in_addr& r){
	   this->m_addr=r;
	   this->m_ul=this->m_addr.S_un.S_addr;
	   this->m_pc=inet_ntoa(this->m_addr);
	   return (*this);
   }

上述的封装类简化了ip地址在不同数据类型之间转换在编码时的重复劳动,但程序的运行效率就会比原来的直接调用要低一点。


调用 示例:

 CIPv4AddressForm ins("192.168.0.10");

std::cout<<ins.ToUInt()<<std::endl;


CIPv4AddressForm ins3;

ins3=ins;

std::cout<<ins3.ToString()<<std::endl;

ins3="168.192.0.1";

PCL(ins3.ToString());








  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值