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));
        }
            public void AddStreamSocketInternal(StreamSocket socket)
            {
                SocketWrapper socketWrapper = new SocketWrapper(manager, socket, null);
                
                // Start receiving messages recursively
                var rcv = socketWrapper.ReceiveMessageAsync();

                socketList.Add(socketWrapper);
                // Update manager so UI can add to list
                manager.AddSocket(socketWrapper);
            }
            // This will fire when the connected peer attempts to open a port for this connection
            // The peer should start a stream socket listener (for TCP)
            private async void OnRemotePortAdded(WiFiDirectServiceSession sender, WiFiDirectServiceRemotePortAddedEventArgs args)
            {
                try
                {
                    ThrowIfDisposed();

                    var endpointPairCollection = args.EndpointPairs;
                    var protocol = args.Protocol;
                    if (endpointPairCollection.Count == 0)
                    {
                        manager.NotifyUser("No endpoint pairs for remote port added event", NotifyType.ErrorMessage);
                        return;
                    }

                    manager.NotifyUser(String.Format("{0} Port {1} Added by remote peer",
                        (protocol == WiFiDirectServiceIPProtocol.Tcp) ? "TCP" : ((protocol == WiFiDirectServiceIPProtocol.Udp) ? "UDP" : "???"),
                        endpointPairCollection[0].RemoteServiceName
                        ),
                        NotifyType.StatusMessage
                        );

                    SocketWrapper socketWrapper = null;

                    if (args.Protocol == WiFiDirectServiceIPProtocol.Tcp)
                    {
                        // Connect to the stream socket listener
                        StreamSocket streamSocket = new StreamSocket();
                        socketWrapper = new SocketWrapper(manager, streamSocket, null);

                        manager.NotifyUser("Connecting to stream socket...", NotifyType.StatusMessage);
                        await streamSocket.ConnectAsync(endpointPairCollection[0]);
                        // Start receiving messages recursively
                        var rcv = socketWrapper.ReceiveMessageAsync();
                        manager.NotifyUser("Stream socket connected", NotifyType.StatusMessage);
                    }
                    else if (args.Protocol == WiFiDirectServiceIPProtocol.Udp)
                    {
                        // Connect a socket over UDP
                        DatagramSocket datagramSocket = new DatagramSocket();
                        socketWrapper = new SocketWrapper(manager, null, datagramSocket);

                        manager.NotifyUser("Connecting to datagram socket...", NotifyType.StatusMessage);
                        await datagramSocket.ConnectAsync(endpointPairCollection[0]);
                        manager.NotifyUser("Datagram socket connected", NotifyType.StatusMessage);
                    }
                    else
                    {
                        manager.NotifyUser("Bad protocol for remote port added event", NotifyType.ErrorMessage);
                        return;
                    }

                    socketList.Add(socketWrapper);
                    // Update manager so UI can add to list
                    manager.AddSocket(socketWrapper);
                }
                catch (Exception ex)
                {
                    manager.NotifyUser("OnRemotePortAdded Failed: " + ex.Message, NotifyType.ErrorMessage);
                }
            }