/interpreter/tags/at2dist091109/src/edu/vub/at/actors/net/comm/Address.java

http://ambienttalk.googlecode.com/ · 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. */
  28. package edu.vub.at.actors.net.comm;
  29. import edu.vub.at.util.logging.Logging;
  30. import java.io.ByteArrayInputStream;
  31. import java.io.ByteArrayOutputStream;
  32. import java.io.DataInputStream;
  33. import java.io.DataOutputStream;
  34. import java.io.IOException;
  35. import java.io.Serializable;
  36. import java.net.InetAddress;
  37. import java.net.ServerSocket;
  38. /**
  39. * Instances of this class represent low-level network addresses of AmbientTalk
  40. * virtual machines.
  41. *
  42. * An <tt>Address</tt> is frequently multicast across the network via UDP, serving
  43. * as the contents of a VM's <i>heartbeat</i>.
  44. *
  45. * Implementation-wise, an <tt>Address</tt> encapsulates an IP address and a port number,
  46. * which is the address on which the {@link ServerSocket} of the {@link MasterConnectionThread}
  47. * is listening for incoming connections.
  48. *
  49. * @author tvcutsem
  50. */
  51. public class Address implements Serializable, Comparable {
  52. /** the maximum size of a serialized address to be transported over UDP */
  53. public static final int MAX_ADDRESS_BYTE_SIZE = 256;
  54. public final InetAddress ipAddress_;
  55. public final int port_;
  56. /** the name of the overlay network to which this AmbientTalk VM belongs */
  57. public final String ambientTalkNetworkName_;
  58. /** an address is serialized at construction time and cached because it is constant */
  59. public final byte[] serializedForm_;
  60. /** the string form is cached because it is frequently used in the compareTo method */
  61. private final String stringForm_;
  62. /**
  63. * @throws RuntimeException if the network name is so long that the serialized form
  64. * of this <tt>Address</tt> would exceed {@link Address#MAX_ADDRESS_BYTE_SIZE}.
  65. */
  66. public Address(InetAddress ipAddress, int port, String ambientTalkNetworkName) {
  67. ipAddress_ = ipAddress;
  68. port_ = port;
  69. ambientTalkNetworkName_ = ambientTalkNetworkName;
  70. serializedForm_ = toBytes();
  71. stringForm_ = ipAddress.toString() + port;
  72. // check for overflow
  73. if (serializedForm_.length > MAX_ADDRESS_BYTE_SIZE) {
  74. throw new RuntimeException("Address too long: " + this.toString());
  75. }
  76. }
  77. /**
  78. * Deserialize a network address manually from a byte stream.
  79. */
  80. public static Address fromBytes(byte[] serializedForm) throws IOException {
  81. ByteArrayInputStream bin = new ByteArrayInputStream(serializedForm);
  82. DataInputStream din = new DataInputStream(bin);
  83. String address = din.readUTF();
  84. InetAddress ipAddress = InetAddress.getByName(address);
  85. int port = din.readInt();
  86. String groupName = din.readUTF();
  87. din.close();
  88. return new Address(ipAddress, port, groupName);
  89. }
  90. /**
  91. * @return whether the receiver address and the parameter denote VMs that are
  92. * connected to the same AmbientTalk overlay network.
  93. */
  94. public boolean inSameNetwork(Address other) {
  95. return ambientTalkNetworkName_.equals(other.ambientTalkNetworkName_);
  96. }
  97. /**
  98. * Compares two addresses based on their internal representation. There is no
  99. * logical ordering defined on addresses. However, it is guaranteed that
  100. * if <code>adr1.compareTo(adr2) > 0</code> then <code>adr2.compareTo(adr1) < 0</code>.
  101. */
  102. public int compareTo(Object otherAddress) {
  103. return stringForm_.compareTo(((Address) otherAddress).stringForm_);
  104. }
  105. public boolean equals(Object other) {
  106. if (other instanceof Address) {
  107. Address otherAddress = (Address) other;
  108. return (ipAddress_.equals(otherAddress.ipAddress_) && port_ == otherAddress.port_)
  109. && (ambientTalkNetworkName_.equals(otherAddress.ambientTalkNetworkName_));
  110. } else {
  111. return false;
  112. }
  113. }
  114. /**
  115. * It is guaranteed that if two addresses are equal, then they map to the same hash code.
  116. */
  117. public int hashCode() {
  118. return ipAddress_.hashCode() | port_;
  119. }
  120. public String toString() {
  121. return ipAddress_.toString() + ":" + port_ + "[" + ambientTalkNetworkName_ + "]";
  122. }
  123. private byte[] toBytes() {
  124. try {
  125. ByteArrayOutputStream bout = new ByteArrayOutputStream();
  126. DataOutputStream dout = new DataOutputStream(bout);
  127. dout.writeUTF(ipAddress_.getHostAddress());
  128. dout.writeInt(port_);
  129. dout.writeUTF(ambientTalkNetworkName_);
  130. dout.close();
  131. return bout.toByteArray();
  132. } catch (IOException e) {
  133. Logging.VirtualMachine_LOG.fatal("Could not construct serialized address:", e);
  134. return null;
  135. }
  136. }
  137. }