// TryManyPooled by Rowland http://home.comcast.net/~rowland3/ // Base class to attempt connections on many possible servers at a given port. // Useful for finding a usable server on an IRC net, for example. // This version uses a thread pool. import java.io.*; import java.net.*; import java.util.*; /** FileEntriesIterator reads a file of tokens as an Iterator **/ class FileEntriesIterator implements Iterator { protected final FileReader fr; protected final StreamTokenizer in; protected int token; protected boolean gotToken; public FileEntriesIterator(String fileSpec) throws Exception { fr= new FileReader(fileSpec); in= new StreamTokenizer(fr); in.resetSyntax(); in.wordChars(33, 127); token= 0; gotToken= false; } protected final void getnext() { if (!gotToken) try { do { token= in.nextToken(); } while (token!=in.TT_EOF && token!=in.TT_WORD); // skip over all else } catch (Exception E) { System.err.println("ERR FileEntriesIterator: "+ E.toString()); token= in.TT_EOF; // encourage caller to can halt gracefully } gotToken= true; } public final boolean hasNext() { if (in== null) return false; getnext(); if (token== in.TT_EOF) return false; return true; } public final Object next() { Object result= null; if (in== null) return null; getnext(); if (token== in.TT_EOF) result= null; else result= in.sval; gotToken= false; return result; } public void remove() { } // not implemented } /** TryMany tries to connect to many possible servers on a given port. Override callbackGotOne() to get useful behavior. **/ public class TryManyPooled implements Runnable { protected final Iterator candidates; final int port; int timeout= 15000; protected boolean debug= false; /** set scanning to false if you want to stop trying for more connections **/ protected boolean scanning= false; protected Thread[] pool= new Thread[10]; class TryThread implements Runnable { public void run() { scanning= true; if (candidates== null) { println("ERR: TryMany: no candidates"); return; } while (candidates.hasNext()) { String candidate= (String)candidates.next(); tryCandidate(candidate); if (!scanning) return; } } } /** constructor to read in candidates from a file **/ public TryManyPooled(String fileSpec, int _port) throws Exception { candidates= new FileEntriesIterator(fileSpec); port= _port; } /** A more general constructor that will use any Iterator **/ public TryManyPooled(Iterator _candidates, int _port) { candidates= _candidates; port= _port; } public void setDebug(boolean _debug) { debug= _debug; } public void setTimeout(int _timeout) { timeout= _timeout; } synchronized boolean hasNext() { return candidates.hasNext(); } synchronized Object next() { return candidates.next(); } public void run() { for (int i=0; i