public async Task <AsyncStringResult> ReceiveMessageAsync(
            SocketWrapper socket
            )
        {
            Exception error   = null;
            bool      success = false;
            string    message = "";

            try
            {
                ThrowIfDisposed();

                WiFiDirectTestLogger.Log(
                    "ReceiveMessageAsync... (Socket={0})",
                    socket.Handle
                    );

                // TCP explicitly receives a message, UDP has a callback
                if (socket.IsTCP)
                {
                    // Wait to receive a message for up to 20 seconds
                    Task receiveMessageTask = socket.ReceiveMessageAsync();
                    if (receiveMessageTask == await Task.WhenAny(receiveMessageTask, Task.Delay(20000)))
                    {
                        WiFiDirectTestLogger.Log(
                            "ReceiveMessageAsync DONE (Socket={0})",
                            socket.Handle
                            );
                    }
                    else
                    {
                        throw new Exception("Timeout waiting for socket to receive message!");
                    }
                }

                socket.WaitForReceive();

                if (!socket.HasReceivedMessages())
                {
                    throw new Exception("Did not actually receive message over socket!");
                }

                while (socket.HasReceivedMessages())
                {
                    WiFiDirectTestLogger.Log("Reading message...");
                    message += socket.GetNextReceivedMessage();
                }

                success = true;
            }
            catch (Exception ex)
            {
                WiFiDirectTestLogger.Log("Exception in SendMessageAsync (this may be expected)");
                error = ex;
            }

            return(new AsyncStringResult(message, success, error));
        }