All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jgroups.stack.IpAddress Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version

package org.jgroups.stack;

import org.jgroups.Address;
import org.jgroups.Constructable;
import org.jgroups.Global;
import org.jgroups.PhysicalAddress;

import java.io.*;
import java.net.*;
import java.util.function.Supplier;


/**
 * Network-dependent address (Internet). Generated by the bottommost layer of the protocol
 * stack (UDP). Contains an InetAddress and port.
 * @author Bela Ban
 */
public class IpAddress implements PhysicalAddress, Constructable {
    protected InetAddress  ip_addr;
    protected int          port;


    // Used only by marshalling
    public IpAddress() {
    }

    /** e.g. 192.168.1.5:7800 */
    public IpAddress(String addr_port) throws Exception {
        int index=addr_port.lastIndexOf(':');
        if(index == -1)
            ip_addr=InetAddress.getByName(addr_port);
        else {
            ip_addr=InetAddress.getByName(addr_port.substring(0, index));
            port=Integer.parseInt(addr_port.substring(index+1));
        }
    }

    public IpAddress(String i, int p) throws UnknownHostException {
        port=p;
        ip_addr=InetAddress.getByName(i);
    }



    public IpAddress(InetAddress i, int p) {
        ip_addr=i; port=p;
        if(this.ip_addr == null)
            setAddressToLocalHost();
    }

    public Supplier create() {
        return IpAddress::new;
    }

    protected void setAddressToLocalHost() {
        try {
            ip_addr=InetAddress.getLocalHost();  // get first NIC found (on multi-homed systems)
        }
        catch(Exception e) {
            ip_addr=null;
        }
        if(ip_addr == null) {
            try {
                ip_addr=InetAddress.getByName(null);
            }
            catch(UnknownHostException e) {
            }
        }
    }

    public IpAddress(int port) {
        this(port, true);
    }

    public IpAddress(int port, boolean set_default_host) {
        this.port=port;
        if(set_default_host)
            setAddressToLocalHost();
    }


    public IpAddress(InetSocketAddress sock_addr) {
        port=sock_addr.getPort();
        ip_addr=sock_addr.getAddress();
    }



    public InetAddress  getIpAddress() {return ip_addr;}
    public  int         getPort()      {return port;}


    /**
     * implements the java.lang.Comparable interface
     * @see java.lang.Comparable
     * @param o - the Object to be compared
     * @return a negative integer, zero, or a positive integer as this object is less than,
     *         equal to, or greater than the specified object.
     * @exception java.lang.ClassCastException - if the specified object's type prevents it
     *            from being compared to this Object.
     */
    public int compareTo(Address o) {
        int h1, h2, rc; // added Nov 7 2005, makes sense with canonical addresses

        if(this == o) return 0;
        if(!(o instanceof IpAddress))
            throw new ClassCastException("comparison between different classes: the other object is " +
                    (o != null? o.getClass() : o));
        IpAddress other = (IpAddress) o;
        if(ip_addr == null)
            if (other.ip_addr == null) return port < other.port ? -1 : (port > other.port ? 1 : 0);
            else return -1;

        h1=ip_addr.hashCode();
        h2=other.ip_addr.hashCode();
        rc=h1 < h2? -1 : h1 > h2? 1 : 0;
        return rc != 0 ? rc : port < other.port ? -1 : (port > other.port ? 1 : 0);
    }


    public boolean equals(Object obj) {
        if(this == obj) return true; // added Nov 7 2005, makes sense with canonical addresses

        if(!(obj instanceof IpAddress))
            return false;
        IpAddress other=(IpAddress)obj;
        boolean sameIP;
        if(this.ip_addr != null)
            sameIP=this.ip_addr.equals(other.ip_addr);
        else
            sameIP=(other.ip_addr == null);
        return sameIP && (this.port == other.port);
    }



    public int hashCode() {
        return ip_addr != null ? ip_addr.hashCode() + port : port;
    }




    public String toString() {
        return printIpAddress();
    }

    public String printIpAddress() {
        return String.format("%s:%d", ip_addr != null? ip_addr.getHostAddress() : "", port);
    }

    public String printIpAddress2() {
        return String.format("%s[%d]", ip_addr != null? ip_addr.getHostAddress() : "localhost", port);
    }


    @Override
    public void writeTo(DataOutput out) throws IOException {
        if(ip_addr != null) {
            byte[] address=ip_addr.getAddress();  // 4 bytes (IPv4) or 16 bytes (IPv6)
            out.writeByte(address.length); // 1 byte
            out.write(address, 0, address.length);
            if(ip_addr instanceof Inet6Address)
                out.writeInt(((Inet6Address)ip_addr).getScopeId());
        }
        else {
            out.writeByte(0);
        }
        out.writeShort(port);
    }

    @Override
    public void readFrom(DataInput in) throws IOException {
        int len=in.readByte();
        if(len > 0 && (len != Global.IPV4_SIZE && len != Global.IPV6_SIZE))
            throw new IOException("length has to be " + Global.IPV4_SIZE + " or " + Global.IPV6_SIZE + " bytes (was " +
                    len + " bytes)");
        byte[] a = new byte[len]; // 4 bytes (IPv4) or 16 bytes (IPv6)
        in.readFully(a);
        if(len == Global.IPV6_SIZE) {
            int scope_id=in.readInt();
            this.ip_addr=Inet6Address.getByAddress(null, a, scope_id);
        }
        else {
            this.ip_addr=InetAddress.getByAddress(a);
        }

        // changed from readShort(): we need the full 65535, with a short we'd only get up to 32K !
        port=in.readUnsignedShort();
    }

    @Override
    public int serializedSize() {
        // length (1 bytes) + 4 bytes for port
        int tmp_size=Global.BYTE_SIZE+ Global.SHORT_SIZE;
        if(ip_addr != null) {
            // 4 bytes for IPv4, 20 for IPv6 (16 + 4 for scope-id)
            tmp_size+=(ip_addr instanceof Inet4Address)? 4 : 20;
        }
        return tmp_size;
    }

    public IpAddress copy() {
        return new IpAddress(ip_addr, port);
    }



}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy