龙仪的家

导航

<2006年7月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

随笔分类

文章分类

收藏夹

随笔档案

文章档案

统计

我的常用网址

代码库之十五-IPV4地址类


这是一个IPV4协议地址族封装,具体也不多说了,看代码就知道了,觉得乱的朋友拷贝下来,贴到VC中看就好了,看到有的朋友贴代码还有折叠着色功能,不知道是用的什么工具,甚是羡慕,知道的告诉我一下吧,大家的支持是我的动力.


/////////////////////////////////////////H//////////////////////////////////////////////////////

#ifndef LGLIB_SOCKETADDRESS_H
#define LGLIB_SOCKETADDRESS_H

#include <winsock2.h>
#include"lg_SyncLock.h"
#include<string>
#include<vector>
//---------------------------------------------------------------------------
using namespace std;

namespace lglib {
 class __LGLIB__ lg_SocketEnv
 {
 public:
  lg_SocketEnv( void ) {
   // Startup windows sockets
   WSADATA wsaData;
   int err;
   err = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
  
   if (err==0){
    if ((LOBYTE(wsaData.wVersion)==2) && (HIBYTE(wsaData.wVersion)==2)){
     // 确认WinSock DLL支持2.0
    }else{
     //MessageBox(NULL,"该系统不支持网络多播","网络初始化错误",MB_OK);
     WSACleanup();
     err = WSAVERNOTSUPPORTED; /* 不支持,失败返回 */
    }
   }
  }
  
  ~lg_SocketEnv( void ) {
   // Shutdown windows sockets
   ::WSACleanup();
  }
 };
 /*!
  * 这是一个独立类模块,可以直接使用。主要提供了主机名->地址或者地址->主机名
  * 的自动转换。也可以通过该类获得本地或远程主机所拥有的地址数量与地址信息。
  *
  * @short IPV4协议地址族。
  */
 class __LGLIB__ lg_SocketAddress
 {
 public:  // 公用数据
 
  static const char ANYIP[]; /*!< 任意IP */
  
 private: // 私有数据
  
  typedef vector<string> StringVector;
  typedef vector<in_addr> IPVector;
  
  string   m_szName; /*!< 机器名称 */
  StringVector  m_arrszAliases; /*!< 别名数组 */
  IPVector  m_arrIpAddress; /*!< IP地址数组 */
  Port_t   m_sPort; /*!< 网络字节顺序的端口号 */
 public:  // 构造/析构
 
  /*!
   * 构造函数。用现有的地址信息构造类,初始化个数据成员。
   *
   * @param addr 地址信息
   */
      lg_SocketAddress( const sockaddr_in& addr );
  
  /*!
   * 明确构造函数,不能作为默认类型转换使用。通过明确给定各初始值,
   * 构造类,初始化各数据成员。
   *
   * @param ip  地址字符串,可以是URL
   * @param port  端口号
   * @param dolookup 是否通过DNS服务器获得主机的详细信息
   */
  explicit lg_SocketAddress( const string& ip = ANYIP,
      Port_t port = 0,
      bool dolookup = false );
      
  /*!
   *析构函数。
   */
      virtual ~lg_SocketAddress( void );
 
 public:  // 运算符
  
  /*!
   * 类型转换运算符,可以将lg_SocketAddress类型转换为sockaddr_in类型。
   */
  operator sockaddr_in() const;
  
  /*!
   * 赋值运算符,将sockaddr_in类型的数据赋值给这个类的各个成员。
   *
   * @param addr 源数据
   * @return 用于a=b=c方式
   */
  const sockaddr_in& operator=( const sockaddr_in& addr );
  
  /*! 比较运算 */
  bool operator==( const sockaddr_in& addr ) const;
  
 public:  // 方法
  /*!
   * 查询主机信息。通过DNS服务器查询主机信息,将个信息保存在相应的
   * 私有数据成员中。
   */
  void lookup( void );
  void lookup( const string& ip );
  /*!
   * 获得主机名。一般需要调用Lookup方法才能获得正确的主机名信息。
   *
   * @return 主机名  
   */
  string getName( void ) const { return m_szName; }
 public:  // 属性
  
  /*!
   * 获得别名。根据所给索引,返回一个别名。注意,索引不能越界,可以通
   * 过getNumAliases属性获得索引边界。一般需要调用Lookup方法才能获得
   * 正确的别名信息。
   *
   * @param index 别名索引(一个主机可以拥有多个别名)
   * @param 别名
   */
  const string& getAliasName( uint32 index = 0 ) const;
  
  /*!
   * 获得IP地址的字符串形式。通过给定的索引获得IP地址的字符串信息。注意,
   * 索引不能越界,可以通过getNumIp属性获得索引边界。一般需要调用Lookup
   * 方法才能获得正确的地址信息。
   *
   * @param index 地址索引(一个主机可以帮定多了地址)
   * @return 字符串形式的IP地址信息。
   */
  string getIpString( uint32 index = 0 ) const;
  
  /*!
   * 获得别名的个数。一般需要调用Lookup方法才能获得正确的信息。
   *
   * @return 别名的个数
   */
  int32 getNumAliases( void ) { return static_cast< int >( m_arrszAliases.size() ); }
  
  /*!
   * 获得IP地址数。一把需要调用Lookup方法才能获得正确的信息。
   *
   * @return ip地址数  
   */
  int32 getNumIp( void ) { return static_cast< int >( m_arrIpAddress.size() ); }
  
  /*!
   * 获得端口号
   *
   * @return  端口号
   */
  Port_t getPort( void ) const;
  
 private: // 私有过程
  
  
 };
};

#endif

////////////////////////////////////////////CPP/////////////////////////////////////////

/* 版权所有 (C) 1997-2004 
 * 创建:  2004年10月20日
 * 描述: TCP/IP协议地址族封装模块
 */
#include "StdAfx.h"
#include "lg_socketaddress.h"
#include "lg_Exception.h"
#pragma comment(lib, "ws2_32.lib")
# define herrno WSAGetLastError()
#include <string>

using namespace std;

namespace lglib {

 static lg_SocketEnv __win32env;
//---------------------------------------------------------------------------
 // 初始化常量成员
 const char lg_SocketAddress::ANYIP[] = "0.0.0.0";
//---------------------------------------------------------------------------
 // 构造函数
 lg_SocketAddress::lg_SocketAddress( const sockaddr_in& addr )
 {
  m_arrIpAddress.push_back( addr.sin_addr );
  m_sPort = addr.sin_port;
 }

//---------------------------------------------------------------------------
 // 明确构造函数
 lg_SocketAddress::lg_SocketAddress( const string& ip,
      Port_t port,
      bool dolookup )
 {
  in_addr Address;
  
  if ( dolookup )
  {
   lookup( ip );
  }
  else
  {
   //将IP地址数据转换为二进制
   if ( ( Address.s_addr = inet_addr( ip.c_str() ) ) == INADDR_NONE )
   {
    //IP地址转换失败,可能是一个域名
    lookup( ip );
   }
   else
   {
    m_arrIpAddress.push_back( Address );
   }
  }
  this->m_sPort = htons( port );
 }
 
//---------------------------------------------------------------------------
 // 析构函数
 lg_SocketAddress::~lg_SocketAddress( void )
 {
 }
 
//---------------------------------------------------------------------------
 // 明确类型转换  sockaddr_in -> lg_SocketAddress
 lg_SocketAddress::operator sockaddr_in() const
 {
  if ( m_arrIpAddress.empty() )
  {
   throw lg_Exception( "lg_SocketAddress::operator sockaddr_in::m_arrIpAddress.empty",
      "IP地址不正确",
      LG_SOCKETADDRESS_NO_IP_CODE );
  }

  sockaddr_in Address;
  Address.sin_family = AF_INET;
  Address.sin_port = m_sPort;
  Address.sin_addr = m_arrIpAddress.front();
  
  return Address;
 }

//---------------------------------------------------------------------------
 // 赋值运算 LG_SocketAddre = sockaddr_in
 const sockaddr_in& lg_SocketAddress::operator=( const sockaddr_in& addr )
 {
  m_szName = "";
  m_arrszAliases.clear();

  m_arrIpAddress.clear();
  m_arrIpAddress.push_back( addr.sin_addr );

  m_sPort = addr.sin_port;

  return addr;
 }
 
//---------------------------------------------------------------------------
 // 比较运算
 bool lg_SocketAddress::operator==( const sockaddr_in& addr ) const
 {
  if ( addr.sin_port == m_sPort &&
   addr.sin_addr.s_addr == m_arrIpAddress.front().s_addr  )
  {
   return true;
  }
  return false;
 }
 
//---------------------------------------------------------------------------
 // 查询主机信息
 void lg_SocketAddress::lookup( const string& ip )
 {
  hostent* hostinfo = NULL;
  hostinfo = gethostbyname( ip.c_str() );
  if ( hostinfo == NULL )
  {
   throw lg_Exception( "lg_SocketAddress::lookup( const string& ip )::gethostbyname", errno );
  }

  m_szName = hostinfo->h_name;
  m_arrszAliases.clear();
  // 保存所有发现的别名在列表中
  if ( hostinfo->h_aliases[0] != NULL )
  {
   for ( char** alias=hostinfo->h_aliases; alias != NULL; alias++ )
   {
    m_arrszAliases.push_back( *alias );
   }
  }

  m_arrIpAddress.clear();
  // 保存所有发现的IP在列表中
  for ( in_addr** addr = reinterpret_cast< in_addr** >( hostinfo->h_addr_list );
   *addr != NULL;addr++ )
  {
   m_arrIpAddress.push_back( **addr );
  }
 }
 
//---------------------------------------------------------------------------
 // 查询主机信息
 void lg_SocketAddress::lookup( void )
 {
  hostent* hostinfo = NULL;
  if ( m_arrIpAddress.empty() )
  {
   throw lg_Exception( "lg_SocketAddress::lookup( void )::gethostbyname",
      "IP地址不正确",
      LG_SOCKETADDRESS_NO_IP_CODE );
  }
  //只是使用列表中的第一个IP
  hostinfo = gethostbyaddr( reinterpret_cast< char* >( &m_arrIpAddress.front() ),
         sizeof( in_addr ),
         AF_INET );
  if ( hostinfo == NULL )
  {
   m_arrszAliases.clear();
   m_szName = "";
   return;
  }

  m_szName = hostinfo->h_name;
  m_arrszAliases.clear();
  
  //保存所有发现的别名在列表中
  if ( hostinfo->h_aliases[0] != NULL )
  {
   try
   {
    for ( char** alias = hostinfo->h_aliases; alias != NULL; alias++ )
    {
     m_arrszAliases.push_back( *alias );
    }
   }
   catch( ... )
   {
   }
  }

  m_arrIpAddress.clear();
  
  //保存所有发现的IP在列表中
  for ( in_addr** addr = reinterpret_cast< in_addr** >( hostinfo->h_addr_list );
   *addr != NULL;addr++ )
  {
   m_arrIpAddress.push_back( **addr );
  }
 }
 
//---------------------------------------------------------------------------
 // 获得别名
 const string& lg_SocketAddress::getAliasName( uint32 index ) const
 {
  if ( index >= m_arrszAliases.size() || index < 0 )
  {
   throw lg_Exception( "lg_SocketAddress::getAliasName",
      "索引越界!",
      LG_SOCKETADDRESS_OFF_RANGE_CODE );
  }
  return m_arrszAliases[index];
 }
 
//---------------------------------------------------------------------------
 // 获得IP地址字符串信息
 string lg_SocketAddress::getIpString( uint32 index ) const
 {
  if ( index >= m_arrIpAddress.size() || index < 0 )
  {
   throw lg_Exception( "lg_SocketAddress::getIpString",
      "索引越界!",
      LG_SOCKETADDRESS_OFF_RANGE_CODE );
  }

  string ip = inet_ntoa( m_arrIpAddress[index] );
  return ip;
 }

//--------------------------------------------------------------------------
 Port_t lg_SocketAddress::getPort( void ) const
 {
  return ntohs( m_sPort );
 }
 
};

posted on 2006-07-31 10:32 龙仪 阅读(1446) 评论(5)  编辑 收藏

评论

# re: 代码库之十五-IPV4地址类 2006-07-31 12:29 晓寒

hehe, 功能没有看。先告诉你怎么贴带颜色的代码:

在编辑blog的时候,选择插入代码,然后选择C#代码。出来以后就有折叠和高亮了。

# :)谢谢 2006-07-31 13:24 龙仪

就是看了你的代码才问的:)代码库里的lib是你写的啊,pfpf

# re: 代码库之十五-IPV4地址类 2006-07-31 17:39 晓寒

代码库里的lib?那个lib?我不知道啊。

# re: 代码库之十五-IPV4地址类 2006-09-06 13:49 dgfdg

你的文章非常精彩,秀逗邀请您加入秀逗博客联盟.中国最大最专业的博客推荐联盟,秀逗博客联盟不截取流量,推荐后的文章指向作者本人的BLOG,文章24小时循环首页展示,真正意义上迅速提升你的博客流量!欢迎注册,注册后将推荐代码添加到自己的BLOG相应位置即可轻松推荐文章,让更多人分享你的文章!后期更有秀逗市场、同心琐秀、商业联盟以及社区陆续登场,更多娱乐功能、商业展示机会,完全免费使用,名人博客,不用再眼红,使用秀逗推荐,流量迅速上升,好的博客,秀逗为您宣传!地址:http://www.sodooo.com

# re: 代码库之十五-IPV4地址类 2008-05-27 14:02 飞凌

好东西,支持

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]