func (na *NetAddress) Equals(other interface{}) bool {
	if o, ok := other.(*NetAddress); ok {
		return na.String() == o.String()
	}
	return false
}
Equals reports whether na and other are the same addresses,
including their ID, IP, and Port.
package p2p
import (
	"encoding/hex"
	"flag"
	"fmt"
	"net"
	"strconv"
	"strings"
	"time"
	cmn "github.com/tendermint/tendermint/libs/common"
)
type NetAddress struct {
	ID   ID     `json:"id"`
	IP   net.IP `json:"ip"`
	Port uint16 `json:"port"`
	str string
}
func IDAddressString(id ID, hostPort string) string {
	return fmt.Sprintf("%s@%s", id, hostPort)
}
func NewNetAddress(id ID, addr net.Addr) *NetAddress {
	tcpAddr, ok := addr.(*net.TCPAddr)
	if !ok {
		if flag.Lookup("test.v") == nil {  
			cmn.PanicSanity(cmn.Fmt("Only TCPAddrs are supported. Got: %v", addr))
		} else {  
			netAddr := NewNetAddressIPPort(net.IP("0.0.0.0"), 0)
			netAddr.ID = id
			return netAddr
		}
	}
	ip := tcpAddr.IP
	port := uint16(tcpAddr.Port)
	na := NewNetAddressIPPort(ip, port)
	na.ID = id
	return na
}
func NewNetAddressString(addr string) (*NetAddress, error) {
	spl := strings.Split(addr, "@")
	if len(spl) < 2 {
		return nil, ErrNetAddressNoID{addr}
	}
	return NewNetAddressStringWithOptionalID(addr)
}
func NewNetAddressStringWithOptionalID(addr string) (*NetAddress, error) {
	addrWithoutProtocol := removeProtocolIfDefined(addr)
	var id ID
	spl := strings.Split(addrWithoutProtocol, "@")
	if len(spl) == 2 {
		idStr := spl[0]
		idBytes, err := hex.DecodeString(idStr)
		if err != nil {
			return nil, ErrNetAddressInvalid{addrWithoutProtocol, err}
		}
		if len(idBytes) != IDByteLength {
			return nil, ErrNetAddressInvalid{
				addrWithoutProtocol,
				fmt.Errorf("invalid hex length - got %d, expected %d", len(idBytes), IDByteLength)}
		}
		id, addrWithoutProtocol = ID(idStr), spl[1]
	}
	host, portStr, err := net.SplitHostPort(addrWithoutProtocol)
	if err != nil {
		return nil, ErrNetAddressInvalid{addrWithoutProtocol, err}
	}
	ip := net.ParseIP(host)
	if ip == nil {
		if len(host) > 0 {
			ips, err := net.LookupIP(host)
			if err != nil {
				return nil, ErrNetAddressLookup{host, err}
			}
			ip = ips[0]
		}
	}
	port, err := strconv.ParseUint(portStr, 10, 16)
	if err != nil {
		return nil, ErrNetAddressInvalid{portStr, err}
	}
	na := NewNetAddressIPPort(ip, uint16(port))
	na.ID = id
	return na, nil
}
func NewNetAddressStrings(addrs []string) ([]*NetAddress, []error) {
	netAddrs := make([]*NetAddress, 0)
	errs := make([]error, 0)
	for _, addr := range addrs {
		netAddr, err := NewNetAddressString(addr)
		if err != nil {
			errs = append(errs, err)
		} else {
			netAddrs = append(netAddrs, netAddr)
		}
	}
	return netAddrs, errs
}
func NewNetAddressIPPort(ip net.IP, port uint16) *NetAddress {
	return &NetAddress{
		IP:   ip,
		Port: port,
	}
}