⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 endpointrouter.java

📁 jxme的一些相关程序,主要是手机上程序开发以及手机和计算机通信的一些程序资料,程序编译需要Ant支持
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
   * Peer Routing Protocol to try to discover one.  We will
   * wait up to a minute for a route to be discovered.
   */
  public EndpointAddress getAddress(String pId) {
    
    // Compacting the cache first is a good idea if we want to
    // get the best route. Note that compactCaches() can be expensive,
    // but:
    //        - it is saving time and network bandwith ahead of time
    //        - the proces of compacting happens only if there has been
    //          a change in the caches.
    //
    // So, all together, this seems to be a good optimization.
    //
    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getAddress for ");
    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("      peer= " + pId);
    
    Route route = null;
    int count = 0;
    
    while (true) {
      
      // Then check if by anychance we can talk to it directly.
      learnLocalRoute(pId);
      
      // So, is there a local route ?
      if (isLocalRoute(pId)) {
        if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Found local address: " + pId + " -> " +
        getLocalRoute(pId).toString());
        return getLocalRoute(pId);
      }
      
      // Otherwise, look for a long route.
      route = getRoute(pId);
      EndpointAddress addr = null;
      
      if (route != null) {
        
        try {
          addr = getLocalRoute(route.router);
          if (addr != null) {
            if (LOG.isEnabledFor(Priority.DEBUG))
              LOG.debug("Found remote address: " + pId + " -> " + addr.toString());
          } else {
            if (LOG.isEnabledFor(Priority.DEBUG))
              LOG.debug("Found no reachable route to " + pId );
          }
          return addr;
        } catch (Exception e) {
          if (LOG.isEnabledFor(Priority.DEBUG)) {
            LOG.debug("getAddress for " + pId +
            "\n     failed with ", e);
          }
          return null;
        }
      }
      
      
      // Trying to recover a route
      if (count == 0) {
        // this is the first time in the loop.
        findRoute(pId);
      }
      
      // Give up after at most 1 minute
      if (++count > 120) {
        if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getAddress is giving up for " + pId);
        break;
      }
      
      // Just wait a bit
      waitABit();
      
    }
    return null;
  }
  
  /**
   * Given a list of addresses, find the fastest reachable address.
   *
   * The address returned must be pingable.<BR>
   * We prefer an address whose protocol is, in order:<BR>
   * <ol>
   * <li>connected and fast.
   * <li>connected and slow.
   * <li>unconnected and fast.
   * <li>unconnected and slow
   * </ol>
   *
   * @param addrs A list of addresses to evaulate reachability.
   */
  public EndpointAddress getBestLocalRoute(Enumeration addrs) {
    
    //todo: Evaluate why peer is an arg.  Remove it if not needed.
    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getBestLocalRoute:");
    
    EndpointProtocol proto = null;
    EndpointAddress addr = null;
    EndpointAddress bestAddr = null;
    String protoName = null;
    boolean direct = false;
    boolean fast = false;
    
    while (addrs.hasMoreElements()) {
      try {
        addr = (EndpointAddress) addrs.nextElement();
        
        protoName = addr.getProtocolName();
        
        // Ignore ourselves
        if (protoName.equals(getProtocolName())) continue;
        
        proto = endpoint.getEndpointProtocolByName(protoName);
        if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("getBestLocalRoute trying: " + addr.toString()
        + " on protocol " + proto.getProtocolName());
        if (proto == null) {
          continue;
        }
        
        if (!proto.allowRouting()) {
          // This protocol should not be used for routing.
          continue;
        }
        
        
        if (!proto.ping(addr)) {
          // This protocol cannot reach the target addr
          continue;
        }
        
        if (bestAddr == null) {
          if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Found: " + addr.toString());
          bestAddr = addr;
        }
        
        if (proto.isConnectionOriented()) {
          if (direct) {
            // There is already a protocol supporting
            // a direct connection to the target addr.
            if (isFast(proto)) {
              return addr;
            }
            continue;
          } else {
            direct = true;
            if (isFast(proto)) {
              return addr;
            } else {
              bestAddr = addr;
              continue;
            }
          }
        } else {
          if (direct) {
            continue;
          } else {
            bestAddr = addr;
            continue;
          }
        }
      } catch (Exception e) {
        // That address is somehow broken.
        // Cache that result for a while (5 minutes).
        triedAndFailed.put(addr,
        new Long(System.currentTimeMillis()));
        continue;
      }
    }
    
    return bestAddr;
  }
  
  boolean isFast(EndpointProtocol p) {
    String name = p.getProtocolName();
    
    return name.equals("tcp") || name.equals("beep");
  }
  
  /**
   * Returns true if the target address is reachable. Otherwise
   * returns false.
   */
  public boolean ping(EndpointAddress addr) {
    
    try {
      return (getAddress(addr.getProtocolName() + "://"
      + addr.getProtocolAddress()) != null);
    } catch (Exception e) {
      return false;
    }
  }
  
  public synchronized boolean isLocalRoute(String pId) {
    
    if (directRoutes.containsKey(pId)) {
      return true;
    }
    return false;
  }
  
  public synchronized EndpointAddress getLocalRoute(String pId) {
    return (EndpointAddress)directRoutes.get(pId);
  }
  
  // Adds a new local route only if it is new. Takes care
  // of deleting a remote route etc. Returns true if the route was added.
  private synchronized void learnLocalRouteSync(String pId,
  EndpointAddress addr) {
    
    
    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("learnLocalRoute:");
    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("   peerId = " + pId);
    
    try {
      directRoutes.put(pId, addr.clone());
    } catch (Exception e) {
      return; // Failed. Keep things as they were.
    }
    
    try {
      // If we had a long route, remove it
      routedRoutes.remove(pId);
    } catch(Exception e2) {
      // Fine.
    }
    
    notifyAll(); // Tell all those that may be waiting for a route
    return;
  }
  
  // Adds a new local route only if it is new. Takes care
  // of deleting a remote route, etc.
  public void learnLocalRoute(String pId) {
    
    // Here we're not synchronized, so this is a hint.
    // If later we decide to add this address and it has been already by
    // another thread it will not do any damage. But we're about to do a big
    // task possibly, so we want to make sure it's not for nothing.
    // That's why this test is important here, and not in the synchronized
    // method.
    
    if (directRoutes.containsKey(pId)) return; // nothing new.
    
    // We presume that we are able to directly talk to this peer and we weren't
    // before. This has do be checked.
    EndpointAddress addr = checkPeer(pId);
    if (addr == null) {
      // No local route
      return;
    }
    
    learnLocalRouteSync(pId, addr);
  }
  
  public synchronized void removeLocalRoute(String pId) {
    
    try {
      directRoutes.remove(pId);
    } catch (Exception e) {
    }
  }
  
  // We could be given the address and remove it from our hash table, but unfortunately
  // our hashtable is in the other direction and so it is much less expensive to
  // start from the destination peer and find-out if the bad direct route is to that peer
  // or to the first hop on a long route.
  private void brokenRoute(String peer) {
    if (isLocalRoute(peer)) {
      removeLocalRoute(peer);
      return;
    }
    
    // Otherwise, look for a long route.
    Route route = getRoute(peer);
    if (route != null) {
      removeLocalRoute(route.router);
      removeRoute(peer);
    }
  }
  
  public synchronized boolean isRoute(String pId) {
    return routedRoutes.get(pId) != null;
  }
  
  public synchronized Route getRoute(String pId) {
    return (Route) routedRoutes.get(pId);
  }
  
  // Check if a route is valid.
  // Currentely, only loops are detected.
  private boolean checkRoute(Route r) {
    
    if (r == null) {
      if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("route is null");
      return false;
    }
    
    if ((r.gateways == null) || (r.gateways.size() == 0)) {
      if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("route is empty");
      return false;
    }
    
    if (r.gateways.contains(localPeerAddr)) {
      // The route does contain this local peer. Using this route
      // would create a loop. Discard.
      if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("route contains this peer - loopback");
      return false;
    }
    
    // Now check for any other potential loops.
    Vector peers = new Vector();
    for (int i=0; i < r.gateways.size(); ++i) {
      try {
        if (peers.contains((String) r.gateways.elementAt(i))) {
          // This is a loop.
          return false;
        } else {
          peers.add(r.gateways.elementAt(i));
        }
      } catch (Exception ez1) {
        // Not much we can do here
        if (LOG.isEnabledFor(Priority.WARN)) LOG.warn("Exception while processing route checking: " + ez1);
        return false;
      }
    }
    // Seems to be a potential good route.
    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("route is ok");
    return true;
  }
  
  // Adds a new long route provided there not a direct one already.
  // Replaces any longer route.
  // return true if the route was truely new.
  private synchronized boolean setRoute(Route r) {
    
    if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("setRoute:");
    if (r == null) {
      return false;
    }
    r.display();
    
    // Here we're synchronized. Check that we do not have that route
    // after all.
    if (directRoutes.containsKey(r.dest)) return false; // nothing new.
    
    // Check if the route makes senses (loop detection)
    if (!checkRoute(r)) {
      // Route is invalid. Drop it.
      if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Route is invalid");
      return false;
    }
    
    if ( !directRoutes.containsKey(r.router)) {
      // We don't know how to reach this route. Ignore.
      if (LOG.isEnabledFor(Priority.DEBUG)) LOG.debug("Unreachable route - ignore");
      return false;
    }
    
    // If the last hop is not in the vector of gateways, add it.
    try {
      String lastInVector = (String) r.gateways.elementAt(0);
      if ((lastInVector != null) && !lastInVector.equals(r.router)) {
        r.gateways.add(0, r.router);
      }
    } catch (Exception ez1) {
      // The vector must be empty, which is not supposed
      // to happen.
      if (LOG.isEnabledFor(Priority.WARN)) LOG.warn("Got an empty route - discard");
      return false;
    }
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -