diff --git a/nbproject/configs/oneMegTenTimesDiscardTwo.properties b/nbproject/configs/oneMegTenTimesDiscardTwo.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/nbproject/configs/oneMegTwice.properties b/nbproject/configs/oneMegTwice.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/runscripts/read1MegTenTimesDiscard2.sh b/runscripts/read1MegTenTimesDiscard2.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ccf007f3aafbbc4e21607da9069445b0fe083827
--- /dev/null
+++ b/runscripts/read1MegTenTimesDiscard2.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+#java -jar LiFiBenchmarkFat.jar -targetip 172.20.82.180 -sz 1M -r 2
+#test:
+java -jar LiFiBenchmarkFat.jar -sz 1M -r 10 -x 2
diff --git a/runscripts/read1MegTwice.sh b/runscripts/read1MegTwice.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b576883547f7bee54c458e5e2a910a6beb4ae22d
--- /dev/null
+++ b/runscripts/read1MegTwice.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+#java -jar LiFiBenchmarkFat.jar -targetip 172.20.82.180 -sz 1M -r 2
+#test:
+java -jar LiFiBenchmarkFat.jar -sz 1M -r 2
diff --git a/src/edu/nps/moves/lifi/LiFiBenchmark.java b/src/edu/nps/moves/lifi/LiFiBenchmark.java
index e13e088a53ef5872b82901979d9121368b0c90c8..05d4797db93f97905e5ef8ed6b7b869f55fbf744 100644
--- a/src/edu/nps/moves/lifi/LiFiBenchmark.java
+++ b/src/edu/nps/moves/lifi/LiFiBenchmark.java
@@ -27,6 +27,8 @@ import java.net.Inet4Address;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import org.apache.commons.cli.*;
 
 /**
@@ -37,21 +39,26 @@ import org.apache.commons.cli.*;
  */
 public class LiFiBenchmark
 {
-
-  public static String DEFAULT_IP = "127.0.0.1";
-  public static int DEFAULT_PORT = 8500;
-  public static int READ_BUFFER_SIZE = 10*1024;
-  public static int WRITE_BUFFER_SIZE = 5*1024;
+  public static String  DEFAULT_IP = "127.0.0.1";
+  public static int     DEFAULT_PORT = 8500;
+  public static int     DEFAULT_REPITITIONS = 1;
+  public static int     DEFAULT_READ_LIMIT = 1500000 * 1024;
+  public static boolean DEFAULT_SERVER_FLAG = false;
+  public static int     DEFAULT_DISCARD_REPS = 0;
   
-  public static int READ_LIMIT = 1500000 * 1024;
+  private String  targetIp = DEFAULT_IP;
+  private int     targetPort = DEFAULT_PORT;
+  private long    readLimit = DEFAULT_READ_LIMIT;
+  private int     reps = DEFAULT_REPITITIONS;
+  private boolean isServer = DEFAULT_SERVER_FLAG;
+  private int     discards = DEFAULT_DISCARD_REPS;
   
-  private String targetIp = DEFAULT_IP;
-  private int targetPort = DEFAULT_PORT;
-  private boolean isServer = false;
-
   private CommandLine cline;
   private Options opts;
 
+  public static int READ_BUFFER_SIZE = 10*1024;
+  public static int WRITE_BUFFER_SIZE = 5*1024;
+  
   public static void main(String[] args)
   {
     LiFiBenchmark bm = new LiFiBenchmark(args);
@@ -61,56 +68,26 @@ public class LiFiBenchmark
   public LiFiBenchmark(String[] args)
   {
     cline = parseCL(args);
+    
     if (cline.hasOption("h")) {
       HelpFormatter formatter = new HelpFormatter();
-      formatter.printHelp("hello", opts);
+      formatter.printHelp("java -jar LiFiBenchmarkFat [options]", opts);
       System.exit(0);
     }
     if (cline.hasOption("targetip"))
       targetIp = cline.getOptionValue("targetip", DEFAULT_IP);
     if (cline.hasOption("targetport"))
       targetPort = Integer.parseInt(cline.getOptionValue("targetport", "" + DEFAULT_PORT));
-
+    if (cline.hasOption("sz"))
+      readLimit = handleSize(cline.getOptionValue("sz"));
+    if (cline.hasOption("r"))
+      reps = Integer.parseInt(cline.getOptionValue("r",""+DEFAULT_REPITITIONS));
+    if (cline.hasOption("x"))
+      discards = Integer.parseInt(cline.getOptionValue("x",""+DEFAULT_DISCARD_REPS))  ;
+    
     isServer = cline.hasOption("server");
   }
-
-  private CommandLine parseCL(String[] args)
-  {
-    opts = new Options();
-    opts.addOption(Option.builder("ip")
-        .hasArg()
-        .required(false)
-        .longOpt("targetip")
-        .desc("The server address from which to read data, in dot-decimal format")
-        .build());
-    opts.addOption(Option.builder("port")
-        .hasArg()
-        .required(false)
-        .longOpt("targetport")
-        .desc("The server port number to connect to, decimal integer")
-        .build());
-    opts.addOption(Option.builder("h")
-        .hasArg(false)
-        .required(false)
-        .longOpt("help")
-        .desc("Print this message")
-        .build());
-    opts.addOption(Option.builder("server")
-        .hasArg(false)
-        .required(false)
-        .desc("Run in server mode, targetip option N/A")
-        .build());
-
-    try {
-      return new DefaultParser().parse(opts, args);
-    }
-    catch (ParseException ex) {
-      System.out.println("Parsing failed: " + ex.getMessage());
-      System.exit(1);
-      return null;
-    }
-  }
-
+  
   public void start()
   {
     if (isServer)
@@ -122,40 +99,45 @@ public class LiFiBenchmark
   private void networkRead()
   {
     System.out.println("Enter networkRead() with " + targetIp + " and " + targetPort);
-    long startms = System.currentTimeMillis();
-    try {
-      int readAcc;
+    System.out.println("Reading " + readLimit + " bytes");
+    System.out.println("Repetitions: "+ reps);
+    if(discards>0) {
+      System.out.println("Ignoring first "+discards+" repetitions");
+      if(discards>=reps) {
+        System.out.println("Error: discards >= repetitions");
+        System.exit(1);
+      }
+    }
+    int repsCount = reps;
+    int discardsCount = discards;
+    
+    while (repsCount-- > 0) {
+      long readAcc;
+      long startms = System.currentTimeMillis();
+      
       try (Socket sock = new Socket(targetIp, targetPort)) {
-        readAcc = 0;
-        System.out.println("Reading " + READ_LIMIT);
+        readAcc = 0l;
         byte[] buff = new byte[READ_BUFFER_SIZE];
         while (true) {
           int read = sock.getInputStream().read(buff);
           if (read == -1)
             break;
           readAcc += read;
-          if (readAcc >= READ_LIMIT)
+          if (readAcc >= readLimit)
             break;
         }
+        if(discardsCount-- <= 0)
+          showRep(startms, readAcc);
+      }
+      catch (IOException ex) {
+        System.out.println("Exception " + ex.getClass().getSimpleName() + " in networkRead(): " + ex.getMessage());
+        System.exit(-1);
       }
-      long endms = System.currentTimeMillis();
-      long span = endms-startms;
-      double spansecs = (double)span / 1000.d;
-      System.out.println("Read " + readAcc + " bytes in "+span+" msec.");
-      //System.out.format("Rate: %.2e bytes/msec%n",((double)readAcc/(double)span));
-      //System.out.format("Rate: %.2e bytes/sec%n",((double)readAcc/spansecs));
-      double bits = (double)readAcc * 8.d;
-      //System.out.format("Rate: %.2e bits/sec%n",(bits/spansecs));
-      System.out.format("Rate: %.2e Mbit/s%n", ((bits/1000000.d)/spansecs));
-      System.out.format("Rate: %.2f Gbit/s%n", ((bits/1000000000.d)/spansecs));
-
-    }
-    catch (IOException ex) {
-      System.out.println("Exception "+ex.getClass().getSimpleName()+ " in networkRead(): "+ex.getMessage());
-      System.exit(-1);
     }
+    if(reps>1)
+      showAverage();
   }
-
+  
   private void doServer()
   {
     try {
@@ -195,4 +177,128 @@ public class LiFiBenchmark
       }
     }).start();
   }
+  
+  private long handleSize(String s)
+  {
+    Pattern pattern = Pattern.compile("(\\d+)([kmg]*)");
+    Matcher m = pattern.matcher(s.toLowerCase());
+    if(m.matches()) {
+      int ret = Integer.parseInt(m.group(1));
+      if(m.group(2).length()<=0)
+        return ret; // no suffix
+      switch(m.group(2).charAt(0))
+      {
+        case 'k':
+          return ret * 1000l;
+        case 'm':
+          return ret * 1000000l;
+        case 'g':
+          return ret * 1000000000l;
+        default:
+          return ret;        
+      }}
+
+    
+    System.out.println("Error on command line.  Don't understand "+s+" argument for byte count");
+    System.exit(1);
+    return -1;  // not executed
+  }
+  
+  private CommandLine parseCL(String[] args)
+  {
+    opts = new Options();
+    opts.addOption(Option.builder("ip")
+        .hasArg()
+        .required(false)
+        .longOpt("targetip")
+        .desc("The server address from which to read data, in dot-decimal format")
+        .build());
+    opts.addOption(Option.builder("port")
+        .hasArg()
+        .required(false)
+        .longOpt("targetport")
+        .desc("The server port number to connect to, decimal integer")
+        .build());
+    opts.addOption(Option.builder("h")
+        .hasArg(false)
+        .required(false)
+        .longOpt("help")
+        .desc("Print this message")
+        .build());
+    opts.addOption(Option.builder("server")
+        .hasArg(false)
+        .required(false)
+        .desc("Run in server mode, targetip, repititions, sz options N/A")
+        .build());
+    opts.addOption(Option.builder("sz")
+        .hasArg()
+        .required(false)
+        .longOpt("bytecount")
+        .desc("\"File size\" transfered in each repetition: 10M, 20g, 30K, 16000, etc.")
+        .build());
+    opts.addOption(Option.builder("r")
+        .hasArg()
+        .required(false)
+        .longOpt("repetitions")
+        .desc("Number of transfers to perform")
+        .build());
+    
+    opts.addOption(Option.builder("x")
+        .hasArg()
+        .required(false)
+        .longOpt("warmup_repetitions")
+        .desc("Number of repetitions at start to ignore when calculating averages")
+        .build());
+
+    try {
+      return new DefaultParser().parse(opts, args);
+    }
+    catch (ParseException ex) {
+      System.out.println("Parsing failed: " + ex.getMessage());
+      System.exit(1);
+      return null;
+    }
+  }
+
+  double spanMsAccum = 0d;
+  double bitsAccum = 0d;
+  double bytesAccum = 0d;
+  private void showRep(long startms, long read)
+  {
+    long endms = System.currentTimeMillis();
+    long span = endms - startms;
+    double spansecs = (double) span / 1000.d;
+    
+    System.out.println();
+    System.out.println("Read " + read + " bytes in " + span + " msec.");
+    //System.out.format("Rate: %.2e bytes/msec%n",((double)readAcc/(double)span));
+    //System.out.format("Rate: %.2e bytes/sec%n",((double)readAcc/spansecs));
+    spanMsAccum += span;
+    bytesAccum+= read;
+    double bits = (double) read * 8.d;
+    //System.out.format("Rate: %.2e bits/sec%n",(bits/spansecs));
+    System.out.format("Rate: %.2e Mbit/s%n", ((bits / 1000000.d) / spansecs));
+    System.out.format("Rate: %.2f Gbit/s%n", ((bits / 1000000000.d) / spansecs));
+    bitsAccum += bits;
+  }
+
+  private void showAverage()
+  {
+    System.out.println();
+    int actReps = reps-discards;
+
+    System.out.println("Averages (last "+actReps+" counted):");
+
+    double bytesAvg = bytesAccum/actReps;
+    double msAvg = spanMsAccum/actReps;
+    double secAvg = msAvg/1000.d;
+    System.out.println("Read " + bytesAvg + " bytes in " + msAvg + " msec.");
+    //System.out.format("Rate: %.2e bytes/msec%n", (bytesAvg / msAvg));
+    //System.out.format("Rate: %.2e bytes/sec%n",((double)readAcc/spansecs));
+
+    double bits = (double) bytesAvg * 8.d;
+    //System.out.format("Rate: %.2e bits/sec%n",(bits/spansecs));
+    System.out.format("Rate: %.2e Mbit/s%n", ((bits / 1000000.d) / (secAvg)));
+    System.out.format("Rate: %.2f Gbit/s%n", ((bits / 1000000000.d) / (secAvg)));
+  }
 }