ACE_INET_Addr類,在這個ACE_網絡框架中,應該是比較重要的輔助類,該類主要封裝了C SOCKET 的地址對象,通過外觀封裝的模式,把struct sockaddr_in封裝在內。方便用戶的操作。
因此個人認爲掌握此類的常用構造方法和常用的成員函數,並深刻的理解,對於後續的學習ACE或者開發ACE網絡應用程序應該會起到很大的幫助。工欲用其器、必先利其器。就先讓我們把ACE_INET_Addr對象深刻的牢記在心中吧。
- /* -*- C++ -*- */
- //=============================================================================
- /**
- * @file INET_Addr.h
- *
- * $Id: INET_Addr.h 78617 2007-06-27 20:40:19Z mesnier_p $
- *
- * @author Douglas C. Schmidt <[email protected]>
- */
- //=============================================================================
- #ifndef ACE_INET_ADDR_H
- #define ACE_INET_ADDR_H
- #include /**/ "ace/pre.h"
- #include "ace/Sock_Connect.h"
- #if !defined (ACE_LACKS_PRAGMA_ONCE)
- # pragma once
- #endif /* ACE_LACKS_PRAGMA_ONCE */
- #include "ace/Addr.h"
- #if defined(ACE_VXWORKS)
- // Needed to get INET_ADDR_LEN
- # include /**/ "inetLib.h"
- #endif /* ACE_VXWORKS */
- ACE_BEGIN_VERSIONED_NAMESPACE_DECL
- /**
- * @class ACE_INET_Addr
- *
- * @brief Defines a C++ wrapper facade for the Internet domain address
- * family format.
- */
- class ACE_Export ACE_INET_Addr : public ACE_Addr
- {
- public:
- // = Initialization methods.
- /// Default constructor.
- /// 默認構造函數
- ACE_INET_Addr (void);
- /// Copy constructor.
- /// 拷貝構造函數
- ACE_INET_Addr (const ACE_INET_Addr &);
- /// Creates an ACE_INET_Addr from a sockaddr_in structure.
- /// 使用參數@addr 地址初始化ACE_INET_Addr對象。
- /// 參數@len 爲 @addr結構地址對象的長度,使用 sizeof(strcut sockaddr_in)
- ACE_INET_Addr (const sockaddr_in *addr, int len);
- /// Creates an ACE_INET_Addr from a <port_number> and the remote
- /// <host_name>. The port number is assumed to be in host byte order.
- /// To set a port already in network byte order, please @see set().
- /// Use address_family to select IPv6 (PF_INET6) vs. IPv4 (PF_INET).
- /// 使用參數 @port_number 和 host_name 構造一個ACE_INET_Addr對象。
- /// @port_number應該爲主機字節序,構造函數需要把它轉換了網絡字節序。
- /// 如果port_number爲網絡字節序,請使用 set成員函數或者set_port_number成員函數。
- /// @address_family 用於指定ACE_INET_Addr的地址類型PF_INET(IPv4)或者PF_INET6(IPv6)
- ACE_INET_Addr (u_short port_number,
- const char host_name[],
- int address_family = AF_UNSPEC);
- /**
- * Initializes an ACE_INET_Addr from the <address>, which can be
- * "ip-number:port-number" (e.g., "tango.cs.wustl.edu:1234" or
- * "128.252.166.57:1234"). If there is no ':' in the <address> it
- * is assumed to be a port number, with the IP address being
- * INADDR_ANY.
- * 使用參數@address初始化一個ACE_INET_Addr對象。
- * address的格式爲 ip-number:port-number 或者 port-number.
- * ip-number 可以爲點分號的IP地址,也可是是域名地址。
- * 如果參數@address沒有提供 ip-number,只提供port-number時,地址被初始化爲INADDR_ANY
- * port-number 爲主機字節序。
- */
- explicit ACE_INET_Addr (const char address[],
- int address_family = AF_UNSPEC);
- /**
- * Creates an ACE_INET_Addr from a <port_number> and an Internet
- * <ip_addr>. This method assumes that <port_number> and <ip_addr>
- * are in host byte order. If you have addressing information in
- * network byte order, @see set().
- * 使用主機字節序的@port_number 和 @ip_addr初始化一個ACE_INET_Addr對象。
- * 如port_number或者 ip_addr爲網絡字節序時,請使用 set成員函數。
- */
- explicit ACE_INET_Addr (u_short port_number,
- ACE_UINT32 ip_addr = INADDR_ANY);
- /// Uses <getservbyname> to create an ACE_INET_Addr from a
- /// <port_name>, the remote <host_name>, and the <protocol>.
- /// 通過 getservbyname API獲得port_name的端口,eg port_name="ftp"時,得到的端口是21.
- ACE_INET_Addr (const char port_name[],
- const char host_name[],
- const char protocol[] = "tcp");
- /**
- * Uses <getservbyname> to create an ACE_INET_Addr from a
- * <port_name>, an Internet <ip_addr>, and the <protocol>. This
- * method assumes that <ip_addr> is in host byte order.
- */
- ACE_INET_Addr (const char port_name[],
- ACE_UINT32 ip_addr,
- const char protocol[] = "tcp");
- #if defined (ACE_HAS_WCHAR)
- ACE_INET_Addr (u_short port_number,
- const wchar_t host_name[],
- int address_family = AF_UNSPEC);
- explicit ACE_INET_Addr (const wchar_t address[],
- int address_family = AF_UNSPEC);
- ACE_INET_Addr (const wchar_t port_name[],
- const wchar_t host_name[],
- const wchar_t protocol[] = ACE_TEXT_WIDE ("tcp"));
- ACE_INET_Addr (const wchar_t port_name[],
- ACE_UINT32 ip_addr,
- const wchar_t protocol[] = ACE_TEXT_WIDE ("tcp"));
- #endif /* ACE_HAS_WCHAR */
- /// Default dtor.
- ~ACE_INET_Addr (void);
- // = Direct initialization methods.
- // = 直接初始化方法。當使用默認構造函數創建一個ACE_INET_Addr對象時,可以使用
- // 下面的來設置一個ACE_INET_Addr對象的地址和端口。
- // These methods are useful after the object has been constructed.
- /// Initializes from another ACE_INET_Addr.
- /// 使用一個已經存在的ACE_INET_Addr對象來初始化本對象。
- int set (const ACE_INET_Addr &);
- /**
- * Initializes an ACE_INET_Addr from a <port_number> and the
- * remote <host_name>.
- * 使用參數@port_number 和@host_name初始化 ACE_INET_Addr 對象。
- * If <encode> is non-zero then <port_number> is
- * converted into network byte order, otherwise it is assumed to be
- * in network byte order already and are passed straight through.
- * 如果參數@encode 爲TRUE(非零),表示需要set函數內部進行網絡字節序的轉換,
- * 也就是此時 port_number屬於主機字節序的值。否則port_number就是已經是網絡
- * 字節序了,無需進行轉換,直接賦值即可。
- * address_family can be used to select IPv4/IPv6 if the OS has
- * IPv6 capability (ACE_HAS_IPV6 is defined). To specify IPv6, use
- * the value AF_INET6. To specify IPv4, use AF_INET.
- * 參數@address_family 用於選定IPv4/IPv6的地址格式。使用AF_INET指定IPv4地址,
- * AF_INET6指定IPv4地址格式。
- */
- int set (u_short port_number,
- const char host_name[],
- int encode = 1,
- int address_family = AF_UNSPEC);
- /**
- * Initializes an ACE_INET_Addr from a @a port_number and an Internet
- * @a ip_addr.
- * 使用參數@port_number 和參數 @ip_addr初始化 ACE_INET_Addr對象。
- * If @a encode is non-zero then the port number and IP address
- * are converted into network byte order, otherwise they are assumed to be
- * in network byte order already and are passed straight through.
- * 如果參數@encode 爲TRUE(非零)時,表面 @port_number、@ip_addr 爲主機字節序,
- * set 函數內部需要把它們轉換爲網絡字節序。否則它們爲網絡字節序,無需而外的轉換
- * 直接賦值。
- * If <map> is non-zero and IPv6 support has been compiled in,
- * then this address will be set to the IPv4-mapped IPv6 address of it.
- */
- int set (u_short port_number,
- ACE_UINT32 ip_addr = INADDR_ANY,
- int encode = 1,
- int map = 0);
- /// Uses <getservbyname> to initialize an ACE_INET_Addr from a
- /// <port_name>, the remote <host_name>, and the <protocol>.
- int set (const char port_name[],
- const char host_name[],
- const char protocol[] = "tcp");
- /**
- * Uses <getservbyname> to initialize an ACE_INET_Addr from a
- * <port_name>, an <ip_addr>, and the <protocol>. This assumes that
- * <ip_addr> is already in network byte order.
- */
- int set (const char port_name[],
- ACE_UINT32 ip_addr,
- const char protocol[] = "tcp");
- /**
- * Initializes an ACE_INET_Addr from the @a addr, which can be
- * "ip-number:port-number" (e.g., "tango.cs.wustl.edu:1234" or
- * "128.252.166.57:1234"). If there is no ':' in the <address> it
- * is assumed to be a port number, with the IP address being
- * INADDR_ANY.
- * 參數@addr格式爲 %s:%d 或者 %d。
- * %s爲 IP地址或者域名, %d 爲服務端口號。
- * 也就是如果addr 數組中沒有 冒號':' 時,此時地址被設置爲 INADD_ANY,端口爲@addr指定。
- */
- int set (const char addr[], int address_family = AF_UNSPEC);
- /// Creates an ACE_INET_Addr from a sockaddr_in structure.
- /// 使用 sockaddr_in 結構設置ACE_INET_Addr對象。
- int set (const sockaddr_in *,
- int len);
- #if defined (ACE_HAS_WCHAR)
- /**
- * 定義寬字符支持的接口。
- */
- int set (u_short port_number,
- const wchar_t host_name[],
- int encode = 1,
- int address_family = AF_UNSPEC);
- int set (const wchar_t port_name[],
- const wchar_t host_name[],
- const wchar_t protocol[] = ACE_TEXT_WIDE ("tcp"));
- int set (const wchar_t port_name[],
- ACE_UINT32 ip_addr,
- const wchar_t protocol[] = ACE_TEXT_WIDE ("tcp"));
- int set (const wchar_t addr[], int address_family = AF_UNSPEC);
- #endif /* ACE_HAS_WCHAR */
- /// Return a pointer to the underlying network address.
- /// 獲得原始的網絡地址指針,根據IPv4或者IPv6,可以得到一個 struct sockaddr地址的指針。
- virtual void *get_addr (void) const;
- int get_addr_size(void) const;
- /// Set a pointer to the address.
- virtual void set_addr (void *, int len);
- /// Set a pointer to the address.
- virtual void set_addr (void *, int len, int map);
- /**
- * Transform the current ACE_INET_Addr address into string format.
- * If <ipaddr_format> is non-0 this produces "ip-number:port-number"
- * (e.g., "128.252.166.57:1234"), whereas if <ipaddr_format> is 0
- * this produces "ip-name:port-number" (e.g.,
- * "tango.cs.wustl.edu:1234"). Returns -1 if the @a size of the
- * <buffer> is too small, else 0.
- * 把地址轉換爲字符串, 參數@ipaddr_format指定轉換的格式,如果
- * @ipaddr_format爲 TRUE(非零)時,轉換爲點分十進制的IP地址格式。否則
- * 可能轉換爲域名的地址格式。
- * @return 成功時返回 0,否則返回 -1,此時參數@buffer的長度太短。
- *
- */
- virtual int addr_to_string (ACE_TCHAR buffer[],
- size_t size,
- int ipaddr_format = 1) const;
- /**
- * Initializes an ACE_INET_Addr from the @a address, which can be
- * "ip-addr:port-number" (e.g., "tango.cs.wustl.edu:1234"),
- * "ip-addr:port-name" (e.g., "tango.cs.wustl.edu:telnet"),
- * "ip-number:port-number" (e.g., "128.252.166.57:1234"), or
- * "ip-number:port-name" (e.g., "128.252.166.57:telnet"). If there
- * is no ':' in the <address> it is assumed to be a port number,
- * with the IP address being INADDR_ANY.
- * 把字符串表示的地址格式轉換爲 ACE_INET_Addr對象的地址。
- * 地址格式可以爲 [{ip-addr|ip-number}:]{port-number|port-name}
- * 如果地址格式沒有包括冒號':'時,函數內部認爲只是設置 port-number|port-name,
- * 地址被設置爲 INADDR_ANY
- */
- virtual int string_to_addr (const char address[],
- int address_family = AF_UNSPEC);
- #if defined (ACE_HAS_WCHAR)
- /*
- virtual int string_to_addr (const char address[]);
- */
- #endif /* ACE_HAS_WCHAR */
- /**
- * Sets the port number without affecting the host name. If
- * <encode> is enabled then <port_number> is converted into network
- * byte order, otherwise it is assumed to be in network byte order
- * already and are passed straight through.
- * 設置ACE_INET_Addr對象的端口部分,不影響地址域。
- * 參數@encode 的意思等同 set函數的@encode參數。
- */
- void set_port_number (u_short,
- int encode = 1);
- /**
- * Sets the address without affecting the port number. If
- * <encode> is enabled then <ip_addr> is converted into network
- * byte order, otherwise it is assumed to be in network byte order
- * already and are passed straight through. The size of the address
- * is specified in the @a len parameter.
- * If <map> is non-zero, IPv6 support has been compiled in, and
- * <ip_addr> is an IPv4 address, then this address is set to the IPv4-mapped
- * IPv6 address of it.
- * 設置ACE_INET_Addr對象的地址部分,不改變地址對象的端口。
- * 參數@enable與set函數的@encode一致。
- * 參數@len指定 參數@ip_addr的長度。
- * 參數@map 爲 TRUE(非零)是,表示支持IPv6地址格式,否則爲IPv4的地址。
- */
- int set_address (const char *ip_addr,
- int len,
- int encode = 1,
- int map = 0);
- #if (defined (__linux__) || defined (ACE_WIN32)) && defined (ACE_HAS_IPV6)
- /**
- * Sets the interface that should be used for this address. This only has
- * an effect when the address is link local, otherwise it does nothing.
- */
- int set_interface (const char *intf_name);
- #endif /* (__linux__ || ACE_WIN32) && ACE_HAS_IPV6 */
- /// Return the port number, converting it into host byte-order.
- u_short get_port_number (void) const;
- /**
- * Return the character representation of the name of the host,
- * storing it in the <hostname> (which is assumed to be
- * <hostnamelen> bytes long). This version is reentrant. If
- * <hostnamelen> is greater than 0 then <hostname> will be
- * NUL-terminated even if -1 is returned.
- */
- int get_host_name (char hostname[],
- size_t hostnamelen) const;
- #if defined (ACE_HAS_WCHAR)
- int get_host_name (wchar_t hostname[],
- size_t hostnamelen) const;
- #endif /* ACE_HAS_WCHAR */
- /**
- * Return the character representation of the hostname. This
- * version is non-reentrant since it returns a pointer to a static
- * data area. You should therefore either (1) do a "deep copy" of
- * the address returned by get_host_name(), e.g., using strdup() or
- * (2) use the "reentrant" version of get_host_name() described
- * above.
- */
- const char *get_host_name (void) const;
- /**
- * Return the "dotted decimal" Internet address representation of
- * the hostname storing it in the @a addr (which is assumed to be
- * <addr_size> bytes long). This version is reentrant.
- */
- const char *get_host_addr (char *addr, int addr_size) const;
- /**
- * Return the "dotted decimal" Internet address representation of
- * the hostname. This version is non-reentrant since it returns a
- * pointer to a static data area. You should therefore either
- * (1) do a "deep copy" of the address returned by get_host_addr(), e.g.,
- * using strdup() or (2) use the "reentrant" version of
- * get_host_addr() described above.
- */
- const char *get_host_addr (void) const;
- /// Return the 4-byte IP address, converting it into host byte
- /// order.
- ACE_UINT32 get_ip_address (void) const;
- /// Return @c true if the IP address is INADDR_ANY or IN6ADDR_ANY.
- bool is_any (void) const;
- /// Return @c true if the IP address is IPv4/IPv6 loopback address.
- bool is_loopback (void) const;
- /// Return @c true if the IP address is IPv4/IPv6 multicast address.
- bool is_multicast (void) const;
- #if defined (ACE_HAS_IPV6)
- /// Return @c true if the IP address is IPv6 linklocal address.
- bool is_linklocal (void) const;
- /// Return @c true if the IP address is IPv4-mapped IPv6 address.
- bool is_ipv4_mapped_ipv6 (void) const;
- /// Return @c true if the IP address is IPv4-compatible IPv6 address.
- bool is_ipv4_compat_ipv6 (void) const;
- #endif /* ACE_HAS_IPV6 */
- /**
- * Returns @c true if @c this is less than @a rhs. In this context,
- * "less than" is defined in terms of IP address and TCP port
- * number. This operator makes it possible to use @c ACE_INET_Addrs
- * in STL maps.
- * 定義次函數,有何實際的應用嗎?比較2個地址的大小有何實際意義?
- *
- */
- bool operator < (const ACE_INET_Addr &rhs) const;
- /// Compare two addresses for equality. The addresses are considered
- /// equal if they contain the same IP address and port number.
- /// 比較2個地址是否相等,包括地址部分和端口部分。
- bool operator == (const ACE_INET_Addr &SAP) const;
- /// Compare two addresses for inequality.
- /// 比較2個地址是否不相等
- bool operator != (const ACE_INET_Addr &SAP) const;
- /// A variation of the equality operator, this method only compares the
- /// IP address and ignores the port number.
- /// 比較2個地址是否相等,只比較地址部分,忽略端口部分。
- bool is_ip_equal (const ACE_INET_Addr &SAP) const;
- /// Computes and returns hash value.
- virtual u_long hash (void) const;
- /// Dump the state of an object.
- void dump (void) const;
- /// Declare the dynamic allocation hooks.
- ACE_ALLOC_HOOK_DECLARE;
- private:
- /// Insure that @a hostname is properly null-terminated.
- int get_host_name_i (char hostname[], size_t hostnamelen) const;
- // Methods to gain access to the actual address of
- // the underlying internet address structure.
- void *ip_addr_pointer (void) const;
- int ip_addr_size (void) const;
- int determine_type (void) const;
- /// Initialize underlying inet_addr_ to default values
- void reset (void);
- /// Underlying representation.
- /// This union uses the knowledge that the two structures share the
- /// first member, sa_family (as all sockaddr structures do).
- union
- {
- sockaddr_in in4_;
- #if defined (ACE_HAS_IPV6)
- sockaddr_in6 in6_;
- #endif /* ACE_HAS_IPV6 */
- } inet_addr_;
- #if defined (ACE_VXWORKS)
- char buf_[INET_ADDR_LEN];
- #endif
- };
- ACE_END_VERSIONED_NAMESPACE_DECL
- #if defined (__ACE_INLINE__)
- #include "ace/INET_Addr.inl"
- #endif /* __ACE_INLINE__ */
- #include /**/ "ace/post.h"
- #endif /* ACE_INET_ADDR_H */
總結:
1.在set、set_port_number、set_address中都提供了一個參數@encode,此參數在構造函數的參數中並沒有提供。因爲也意味着,使用任何一個構造函數來創建一個ACE_INET_Addr對象時,其地址和端口必須是主機字節序的。如果地址或者端口爲網絡字節序時,必須轉換爲主機字節序纔可以使用構造函數。或者使用默認的構造函數,在通過set、set_port_number、set_address等成員函數,指定encode參數爲FALSE(0)時,也可以直接把網絡字節序的地址和端口設置給ACE_INET_Addr對象。如果地址和端口是2中不同的字節序,需要分別使用set_address和set_port_number進行設置,否則就可以使用set函數一次性設置地址和端口。
2.比較2個ACE_INET_Addr對象的相等性。 根據情況使用不同的成員函數。
地址和端口都要相等時,使用 ==進行比較。
只比較地址時,忽略端口時。使用 is_ip_equal 成員函數。