package com.limegroup.gnutella.udpconnect; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.limegroup.gnutella.ActivityCallback; import com.limegroup.gnutella.stubs.ActivityCallbackStub; import com.limegroup.gnutella.Connection; import com.limegroup.gnutella.Downloader; import com.limegroup.gnutella.Endpoint; import com.limegroup.gnutella.ErrorCallback; import com.limegroup.gnutella.ErrorService; import com.limegroup.gnutella.FileDesc; import com.limegroup.gnutella.FileManagerEvent; import com.limegroup.gnutella.GUID; import com.limegroup.gnutella.RemoteFileDesc; import com.limegroup.gnutella.RouterService; import com.limegroup.gnutella.UDPService; import com.limegroup.gnutella.Uploader; import com.limegroup.gnutella.browser.MagnetOptions; import com.limegroup.gnutella.chat.Chatter; import com.limegroup.gnutella.search.HostData; import com.limegroup.gnutella.util.ManagedThread; import com.limegroup.gnutella.version.UpdateInformation; /** * A standalone program for testing UDPConnections across machines. */ public class UStandalone extends ActivityCallbackStub implements ActivityCallback, ErrorCallback { private static final Log LOG = LogFactory.getLog(UStandalone.class); public static void main(String args[]) { ActivityCallback callback = new UStandalone(); RouterService service = new RouterService(callback); service.start(); LOG.debug("Starting up ..."); waitOnUDP(); LOG.debug("UDPServices up ..."); UDPService.instance().setReceiveSolicited(true); try { Thread.sleep(1000); } catch (InterruptedException ie){} for ( ; ;) { log("Go ..."); try { InetAddress remoteIP = InetAddress.getByName(args[0]); log2("InetAddress: "+remoteIP+" port:"+ Integer.parseInt(args[1]) ); UDPConnection usock = new UDPConnection(remoteIP, Integer.parseInt(args[1])); log2("Created UDPSocket"); if ( args.length == 2 ) { tlogstart("Starting SimpleTest:"); simpleTest(usock); } else if (args[2].equals("-ec")) { tlogstart("Starting EchoClient:"); echoClient(usock, TARGET_BYTES); } else if (args[2].equals("-es")) { tlogstart("Starting EchoServer:"); echoServer(usock, TARGET_BYTES); } else if (args[2].equals("-ecb")) { tlogstart("Starting EchoClientBlock:"); echoClientBlock(usock, TARGET_BLOCKS); } else if (args[2].equals("-esb")) { tlogstart("Starting EchoServerBlock:"); echoServerBlock(usock, TARGET_BLOCKS); } else if (args[2].equals("-uc")) { tlogstart("Starting UnidirectionalClient:"); unidirectionalClient(usock, TARGET_BYTES); } else if (args[2].equals("-us")) { tlogstart("Starting UnidirectionalServer:"); unidirectionalServer(usock, TARGET_BYTES); } usock.close(); break; } catch (IOException e) { e.printStackTrace(); log("Exiting ..."); System.exit(1); } } log("Shutdown ..."); RouterService.shutdown(); } private static void log(String str) { } private static void log2(String str) { LOG.debug(str); } private static void tlogstart(String str) { LOG.debug("start" + str); } private static void tlogend(String str) { LOG.debug("end "+str); } /** The amount of data to transfer */ private static int TARGET_BYTES = 2000000; private static int TARGET_BLOCKS = 4096; /** A boolean that tracks whether the read thread was successful */ private static boolean readSuccess = false; public static boolean echoClient(UDPConnection usock, int numBytes) throws IOException { OutputStream ostream = usock.getOutputStream(); InputStream istream = usock.getInputStream(); readSuccess = false; ClientReader reader = new ClientReader(istream, numBytes); reader.start(); for (int i = 0; i < numBytes; i++) { ostream.write(i % 256); if ( (i % 1000) == 0 ) log2("Write status: "+i); } log("Done write"); try { reader.join(); } catch (InterruptedException ie){} tlogend("Done echoClient test"); return readSuccess; } static class ClientReader extends ManagedThread { InputStream istream; int numBytes; public ClientReader(InputStream istream, int numBytes) { super ("ClientReader"); this.istream = istream; this.numBytes = numBytes; } public void managedRun() { int rval; log2("Begin read"); try { for (int i = 0; i < numBytes; i++) { rval = istream.read(); if ( rval != (i % 256) ) { log2("Error on read expected: "+i +" received: "+rval); break; } else log("Properly recieved: "+i); if ( (i % 1000) == 0 ) log2("Read status: "+i); } readSuccess = true; } catch (IOException e) { throw new RuntimeException(e); } log2("Done read"); } } public static boolean echoServer(UDPConnection usock, int numBytes) throws IOException { OutputStream ostream = usock.getOutputStream(); InputStream istream = usock.getInputStream(); boolean success = false; int rval; for (int i = 0; i < numBytes; i++) { rval = istream.read(); if ( rval != (i % 256) ) { log2("Error on read expected: "+i +" received: "+rval); return false; } if ( (i % 1000) == 0 ) log2("Echo status: "+i); ostream.write(rval); } success = true; log("Done echo"); try { Thread.sleep(1*1000); } catch (InterruptedException ie){} tlogend("Done echoServer test"); return success; } public static boolean echoClientBlock(UDPConnection usock, int numBlocks) throws IOException { OutputStream ostream = usock.getOutputStream(); InputStream istream = usock.getInputStream(); readSuccess = false; ClientBlockReader reader = new ClientBlockReader(istream, numBlocks); reader.start(); // setup transfer data byte bdata[] = new byte[512]; for (int i = 0; i < 512; i++) bdata[i] = (byte) (i % 256); for (int i = 0; i < numBlocks; i++) { ostream.write(bdata, 0, 512); if ( (i % 8) == 0 ) log2("Write status: "+i*512+ " time:"+System.currentTimeMillis()); } log("Done write"); try { reader.join(); } catch (InterruptedException ie){} tlogend("Done echoClientBlock test"); return readSuccess; } static class ClientBlockReader extends ManagedThread { InputStream istream; int numBlocks; public ClientBlockReader(InputStream istream, int numBlocks) { this.istream = istream; this.numBlocks = numBlocks; } public void managedRun() { log2("Begin read"); byte bdata[] = new byte[512]; int btest; int len; int printTarget = 0; try { for (int i = 0; i < 512 * numBlocks; i += len) { len = istream.read(bdata); if ( len != 512 ) log2("Abnormal data size: "+len+" loc: "+i); for (int j = 0; j < len; j++) { btest = bdata[j] & 0xff; if ( btest != ((i+j) % 256) ) { log2("Error on read expected: "+(i+j) +" received: "+bdata[j]); return; } if ( (i+j) > printTarget ) { log2("Read status: "+i+ " time:"+System.currentTimeMillis()); printTarget = i+j+1024; } } } readSuccess = true; } catch (IOException e) { throw new RuntimeException(e); } log2("Done read"); } } public static boolean echoServerBlock(UDPConnection usock, int numBlocks) throws IOException { OutputStream ostream = usock.getOutputStream(); InputStream istream = usock.getInputStream(); byte bdata[] = new byte[512]; boolean success = false; int btest; int len = 0; for (int i = 0; i < 512 * numBlocks; i += len) { len = istream.read(bdata); if ( len != 512 ) log2("Abnormal data size: "+len+" loc: "+i); for (int j = 0; j < len; j++) { btest = bdata[j] & 0xff; if ( btest != ((i+j) % 256) ) { log2("Error on echo expected: "+(i+j) +" received: "+bdata[j]); return false; } if ( ((i+j) % 1024) == 0 ) log2("Echo status: "+i+ " time:"+System.currentTimeMillis()); } ostream.write(bdata, 0, len); } success = true; log("Done echoBlock"); try { Thread.sleep(1*1000); } catch (InterruptedException ie){} tlogend("Done echoServerBlock test"); return success; } public static boolean unidirectionalClient(UDPConnection usock, int numBytes) throws IOException { OutputStream ostream = usock.getOutputStream(); boolean success = false; int i = 0; for (i = 0; i < numBytes; i++) { ostream.write(i % 256); if ( (i % 1000) == 0 ) log2("Write status: "+i); } success = true; log2("Write reached: "+i); try { Thread.sleep(1*1000); } catch (InterruptedException ie){} tlogend("Done unidirectionalClient test"); return success; } public static boolean unidirectionalServer(UDPConnection usock, int numBytes) throws IOException { InputStream istream = usock.getInputStream(); boolean success = false; int rval; int i = 0; for (i = 0; i < numBytes; i++) { rval = istream.read(); if ( rval != (i % 256) ) { log2("Error on read expected: "+i +" received: "+rval); break; } else { if ( (i % 1000) == 0 ) log2("Read Properly received: "+i); } } success = true; log2("Read reached: "+i); try { Thread.sleep(1*1000); } catch (InterruptedException ie){} tlogend("Done unidirectionalServer test"); return success; } private static void simpleTest(UDPConnection usock) throws IOException { OutputStream ostream = usock.getOutputStream(); log2("Created OutputStream"); ostream.write(new byte[50]); ostream.write(new byte[50]); try { Thread.sleep(1*1000); } catch (InterruptedException ie){} ostream.write(new byte[500]); ostream.write(new byte[500]); try { Thread.sleep(1*1000); } catch (InterruptedException ie){} ostream.write(new byte[500]); ostream.write(new byte[500]); try { Thread.sleep(2*1000); } catch (InterruptedException ie){} log2("Done sleep"); tlogend("Done simple test"); } private static void waitOnUDP() { int waits = 0; while(!UDPService.instance().isListening() && waits < 10) { try { Thread.sleep(600); } catch (InterruptedException e) { // Should never happen. ErrorService.error(e); } waits++; } if ( waits >= 10 ) { log2("UDP didn't make it up ..."); log2("Bubye ..."); throw new RuntimeException("no UDP"); } } /////////////////////////// ActivityCallback methods ////////////////////// public void connectionInitializing(Connection c) { } public void connectionInitialized(Connection c) { } public void connectionClosed(Connection c) { } public void knownHost(Endpoint e) { } public void handleQueryResult(RemoteFileDesc rfd ,HostData data, Set loc) { } public void handleQueryString( String query ) { } public void error(int errorCode) { error(errorCode, null); } public void error(Throwable problem, String msg) { problem.printStackTrace(); System.out.println(msg); } public void error(Throwable problem) { problem.printStackTrace(); } public void error(int message, Throwable t) { System.out.println("Error: "+message); t.printStackTrace(); } public void addressStateChanged() {} /////////////////////////////////////////////////////////////////////////// public boolean overwriteFile(String file) {return false;}; public void addDownload(Downloader mgr) {} public void removeDownload(Downloader mgr) {} public void addUpload(Uploader mgr) {} public void removeUpload(Uploader mgr) {} public void setPort(int port){} public int getNumUploads(){ return 0; } public void addSharedDirectory(File file, File parent) {} public void addSharedFile(FileDesc file, File parent) {} public boolean warnAboutSharingSensitiveDirectory(final File dir) { return false; } public void handleSharedFileUpdate(File file) {} public void clearSharedFiles() {} public void acceptChat(Chatter chat) {} public void receiveMessage(Chatter chat) {} public void chatUnavailable(Chatter chatter) {} public void chatErrorMessage(Chatter chatter, String st) {} public void downloadsComplete() {} public void fileManagerLoaded() {} public void uploadsComplete() {} public void promptAboutCorruptDownload(Downloader dloader) { dloader.discardCorruptDownload(false); } public void restoreApplication() {} public void showDownloads() {} public String getHostValue(String key){ return null; } public void browseHostFailed(GUID guid) {} public void setAnnotateEnabled(boolean enabled) {} public void updateAvailable(UpdateInformation uc) {} public boolean isQueryAlive(GUID guid) { return false; } public void componentLoading(String component) {} public void handleFileEvent(FileManagerEvent fme) {} public void fileManagerLoading() {} public boolean handleMagnets(final MagnetOptions[] magnets) { return false; } public void acceptedIncomingChanged(boolean status) { } }