/interpreter/tags/at2dist041108/src/edu/vub/at/actors/net/comm/Address.java
Java | 155 lines | 73 code | 18 blank | 64 comment | 6 complexity | fe76f1c9be69b370e2c69fbd57af4dab MD5 | raw file
1/** 2 * AmbientTalk/2 Project 3 * Address.java created on 2-apr-2007 at 10:52:36 4 * (c) Programming Technology Lab, 2006 - 2007 5 * Authors: Tom Van Cutsem & Stijn Mostinckx 6 * 7 * Permission is hereby granted, free of charge, to any person 8 * obtaining a copy of this software and associated documentation 9 * files (the "Software"), to deal in the Software without 10 * restriction, including without limitation the rights to use, 11 * copy, modify, merge, publish, distribute, sublicense, and/or 12 * sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following 14 * conditions: 15 * 16 * The above copyright notice and this permission notice shall be 17 * included in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 * OTHER DEALINGS IN THE SOFTWARE. 27 */ 28package edu.vub.at.actors.net.comm; 29 30import edu.vub.at.util.logging.Logging; 31 32import java.io.ByteArrayInputStream; 33import java.io.ByteArrayOutputStream; 34import java.io.DataInputStream; 35import java.io.DataOutputStream; 36import java.io.IOException; 37import java.io.Serializable; 38import java.net.InetAddress; 39import java.net.ServerSocket; 40 41/** 42 * Instances of this class represent low-level network addresses of AmbientTalk 43 * virtual machines. 44 * 45 * An <tt>Address</tt> is frequently multicast across the network via UDP, serving 46 * as the contents of a VM's <i>heartbeat</i>. 47 * 48 * Implementation-wise, an <tt>Address</tt> encapsulates an IP address and a port number, 49 * which is the address on which the {@link ServerSocket} of the {@link MasterConnectionThread} 50 * is listening for incoming connections. 51 * 52 * @author tvcutsem 53 */ 54public class Address implements Serializable, Comparable { 55 56 /** the maximum size of a serialized address to be transported over UDP */ 57 public static final int MAX_ADDRESS_BYTE_SIZE = 256; 58 59 public final InetAddress ipAddress_; 60 public final int port_; 61 62 /** the name of the overlay network to which this AmbientTalk VM belongs */ 63 public final String ambientTalkNetworkName_; 64 65 /** an address is serialized at construction time and cached because it is constant */ 66 public final byte[] serializedForm_; 67 68 /** the string form is cached because it is frequently used in the compareTo method */ 69 private final String stringForm_; 70 71 /** 72 * @throws RuntimeException if the network name is so long that the serialized form 73 * of this <tt>Address</tt> would exceed {@link Address#MAX_ADDRESS_BYTE_SIZE}. 74 */ 75 public Address(InetAddress ipAddress, int port, String ambientTalkNetworkName) { 76 ipAddress_ = ipAddress; 77 port_ = port; 78 ambientTalkNetworkName_ = ambientTalkNetworkName; 79 serializedForm_ = toBytes(); 80 stringForm_ = ipAddress.toString() + port; 81 82 // check for overflow 83 if (serializedForm_.length > MAX_ADDRESS_BYTE_SIZE) { 84 throw new RuntimeException("Address too long: " + this.toString()); 85 } 86 } 87 88 /** 89 * Deserialize a network address manually from a byte stream. 90 */ 91 public static Address fromBytes(byte[] serializedForm) throws IOException { 92 ByteArrayInputStream bin = new ByteArrayInputStream(serializedForm); 93 DataInputStream din = new DataInputStream(bin); 94 String address = din.readUTF(); 95 InetAddress ipAddress = InetAddress.getByName(address); 96 int port = din.readInt(); 97 String groupName = din.readUTF(); 98 din.close(); 99 return new Address(ipAddress, port, groupName); 100 } 101 102 /** 103 * @return whether the receiver address and the parameter denote VMs that are 104 * connected to the same AmbientTalk overlay network. 105 */ 106 public boolean inSameNetwork(Address other) { 107 return ambientTalkNetworkName_.equals(other.ambientTalkNetworkName_); 108 } 109 110 /** 111 * Compares two addresses based on their internal representation. There is no 112 * logical ordering defined on addresses. However, it is guaranteed that 113 * if <code>adr1.compareTo(adr2) > 0</code> then <code>adr2.compareTo(adr1) < 0</code>. 114 */ 115 public int compareTo(Object otherAddress) { 116 return stringForm_.compareTo(((Address) otherAddress).stringForm_); 117 } 118 119 public boolean equals(Object other) { 120 if (other instanceof Address) { 121 Address otherAddress = (Address) other; 122 return (ipAddress_.equals(otherAddress.ipAddress_) && port_ == otherAddress.port_) 123 && (ambientTalkNetworkName_.equals(otherAddress.ambientTalkNetworkName_)); 124 } else { 125 return false; 126 } 127 } 128 129 /** 130 * It is guaranteed that if two addresses are equal, then they map to the same hash code. 131 */ 132 public int hashCode() { 133 return ipAddress_.hashCode() | port_; 134 } 135 136 public String toString() { 137 return ipAddress_.toString() + ":" + port_ + "[" + ambientTalkNetworkName_ + "]"; 138 } 139 140 private byte[] toBytes() { 141 try { 142 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 143 DataOutputStream dout = new DataOutputStream(bout); 144 dout.writeUTF(ipAddress_.getHostAddress()); 145 dout.writeInt(port_); 146 dout.writeUTF(ambientTalkNetworkName_); 147 dout.close(); 148 return bout.toByteArray(); 149 } catch (IOException e) { 150 Logging.VirtualMachine_LOG.fatal("Could not construct serialized address:", e); 151 return null; 152 } 153 } 154 155}