diff --git a/README.md b/README.md
index cb6d69e09ad7aab6c7676b2aae8c310539d286b4..b7b0c4585e5bbc5c6d533c7db63579fde1928d32 100644
--- a/README.md
+++ b/README.md
@@ -140,20 +140,22 @@ Full usage of client can be found with `client --help`:
 
 ```
 $ ./client --help
+Runs a client for cMix anonymous communication platform
+
 Usage:
   client [flags]
   client [command]
 
 Available Commands:
-  generate    Generates version and dependency information for the Elixxir binary
-  getndf      Download the network definition file from the network and print it.
-  group       Group commands for cMix client
-  help        Help about any command
-  init        Initialize a user ID but do not connect to the network
-  proto       Load client with a proto client JSON file.
-  single      Send and respond to single-use messages.
-  ud          Register for and search users using the xx network user discovery service.
-  version     Print the version and dependency information for the Elixxir binary
+  fileTransfer Send and receive file for cMix client
+  generate     Generates version and dependency information for the Elixxir binary
+  getndf       Download the network definition file from the network and print it.
+  group        Group commands for cMix client
+  help         Help about any command
+  init         Initialize a user ID but do not connect to the network
+  single       Send and respond to single-use messages.
+  ud           Register for and search users using the xx network user discovery service.
+  version      Print the version and dependency information for the Elixxir binary
 
 Flags:
       --accept-channel            Accept the channel request for the corresponding recipient ID
@@ -173,8 +175,8 @@ Flags:
   -n, --ndf string                Path to the network definition JSON file (default "ndf.json")
   -p, --password string           Password to the session file
       --profile-cpu string        Enable cpu profiling to this file
-      --protoUserOut string       Path to which a normally constructed client will write proto user JSON file (default "protoUser.json")
-      --protoUserPath string      Path to proto user JSON file containing cryptographic primitives the client will load (default "protoUser.json")
+      --protoUserOut string       Path to which a normally constructed client will write proto user JSON file
+      --protoUserPath string      Path to proto user JSON file containing cryptographic primitives the client will load
       --receiveCount uint         How many messages we should wait for before quitting (default 1)
       --regcode string            Identity code (optional)
       --send-auth-request         Send an auth request to the specified destination and waitfor confirmation
@@ -186,9 +188,9 @@ Flags:
       --unsafe                    Send raw, unsafe messages without e2e encryption.
       --unsafe-channel-creation   Turns off the user identity authenticated channel check, automatically approving authenticated channels
       --verboseRoundTracking      Verbose round tracking, keeps track and prints all rounds the client was aware of while running. Defaults to false if not set.
+      --verify-sends              Ensure successful message sending by checking for round completion
       --waitTimeout uint          The number of seconds to wait for messages to arrive (default 15)
   -w, --writeContact string       Write contact information, if any, to this file,  defaults to stdout (default "-")
-                                  file
 
 Use "client [command] --help" for more information about a command.
 ```
diff --git a/cmd/root.go b/cmd/root.go
index a2c9db19265e702aec3c5d268185cd2156b3b8dd..35a24ac42149afc3085f0eae0924aa53fcd0ba33 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -12,7 +12,6 @@ import (
 	"encoding/base64"
 	"encoding/binary"
 	"encoding/hex"
-	"errors"
 	"fmt"
 	"github.com/spf13/cobra"
 	jww "github.com/spf13/jwalterweatherman"
@@ -198,35 +197,61 @@ var rootCmd = &cobra.Command{
 				go func(i int) {
 					defer wg.Done()
 					fmt.Printf("Sending to %s: %s\n", recipientID, msgBody)
-					var roundIDs []id.Round
-					var roundTimeout time.Duration
-					if unsafe {
-						roundIDs, err = client.SendUnsafe(msg,
-							paramsUnsafe)
-						roundTimeout = paramsUnsafe.Timeout
-					} else {
-						roundIDs, _, _, err = client.SendE2E(msg,
-							paramsE2E)
-						roundTimeout = paramsE2E.Timeout
-					}
-					if err != nil {
-						jww.FATAL.Panicf("%+v", err)
-					}
-
-					// Construct the callback function which prints out the rounds' results
-					f := func(allRoundsSucceeded, timedOut bool,
-						rounds map[id.Round]api.RoundResult) {
-						printRoundResults(allRoundsSucceeded, timedOut, rounds, roundIDs, msg)
-					}
-
-					// Have the client report back the round results
-					err = errors.New("derp")
-					for j := 0; j < 5 && err != nil; j++ {
-						err = client.GetRoundResults(roundIDs, roundTimeout, f)
-					}
-
-					if err != nil {
-						jww.FATAL.Panicf("Message sending for send %d failed: %+v", i, err)
+					for {
+						// Send messages
+						var roundIDs []id.Round
+						var roundTimeout time.Duration
+						if unsafe {
+							roundIDs, err = client.SendUnsafe(msg,
+								paramsUnsafe)
+							roundTimeout = paramsUnsafe.Timeout
+						} else {
+							roundIDs, _, _, err = client.SendE2E(msg,
+								paramsE2E)
+							roundTimeout = paramsE2E.Timeout
+						}
+						if err != nil {
+							jww.FATAL.Panicf("%+v", err)
+						}
+
+						if viper.GetBool("verify-sends") { // Verify message sends were successful
+							retryChan := make(chan struct{})
+							done := make(chan struct{}, 1)
+
+							// Construct the callback function which
+							// verifies successful message send or retries
+							f := func(allRoundsSucceeded, timedOut bool,
+								rounds map[id.Round]api.RoundResult) {
+								printRoundResults(allRoundsSucceeded, timedOut, rounds, roundIDs, msg)
+								if !allRoundsSucceeded {
+									retryChan <- struct{}{}
+								} else {
+									done <- struct{}{}
+								}
+							}
+
+							// Monitor rounds for results
+							err = client.GetRoundResults(roundIDs, roundTimeout, f)
+							if err != nil {
+								jww.DEBUG.Printf("Could not verify messages were sent successfully, resending messages...")
+								continue
+							}
+
+							select {
+							case <-retryChan:
+								// On a retry, go to the top of the loop
+								jww.DEBUG.Printf("Messages were not sent successfully, resending messages...")
+								continue
+							case <-done:
+								// Close channels on verification success
+								close(done)
+								close(retryChan)
+								break
+							}
+
+						}
+
+						break
 					}
 				}(i)
 			}
@@ -842,6 +867,10 @@ func init() {
 		"", 500, "The delay between sending the messages in ms")
 	viper.BindPFlag("sendDelay", rootCmd.Flags().Lookup("sendDelay"))
 
+	rootCmd.Flags().BoolP("verify-sends", "", false,
+		"Ensure successful message sending by checking for round completion")
+	viper.BindPFlag("verify-sends", rootCmd.Flags().Lookup("verify-sends"))
+
 	rootCmd.Flags().UintP("receiveCount",
 		"", 1, "How many messages we should wait for before quitting")
 	viper.BindPFlag("receiveCount", rootCmd.Flags().Lookup("receiveCount"))