从 UWP 获取 TCP 服务器上的实时数据(更新)

Get the live data on TCP server from UWP (UPDATED)

下面是一种基本上将数据发送到 TCP 服务器的方法。

         UPDATE BEGINS HERE: 
 //////////////////////////////////
 private string FormatValueByPresentation(IBuffer buffer, GattPresentationFormat format)
    {
        // BT_Code: For the purpose of this sample, this function converts only UInt32 and
        // UTF-8 buffers to readable text. It can be extended to support other formats if your app needs them.
        byte[] data;
        CryptographicBuffer.CopyToByteArray(buffer, out data);
        if (format != null)
        {
            if (format.FormatType == GattPresentationFormatTypes.UInt32 && data.Length >= 4)
            {
                return BitConverter.ToInt32(data, 0).ToString();
            }
            else if (format.FormatType == GattPresentationFormatTypes.Utf8)
            {
                try
                {
                    return Encoding.UTF8.GetString(data);
                }
                catch (ArgumentException)
                {
                    return "(error: Invalid UTF-8 string)";
                }
            }
            else
            {
                // Add support for other format types as needed.
                return "Unsupported format: " + CryptographicBuffer.EncodeToHexString(buffer);
            }
        }
        else if (data != null)
        {
            // We don't know what format to use. Let's try some well-known profiles, or default back to UTF-8.
            if (selectedCharacteristic.Uuid.Equals(GattCharacteristicUuids.HeartRateMeasurement))
            {
                try
                { 
                    ///////LOOK HERE/////
                    **string b = ParseHeartRateValue(data).ToString();
                    TrySend(b); 
                    //return "Heart Rate: " + ParseHeartRateValue(data).ToString();
                    return "Heart Rate: " + b;** 
                }
                catch (ArgumentException)
                {
                    return "Heart Rate: (unable to parse)";
                }
            }
            else if (selectedCharacteristic.Uuid.Equals(GattCharacteristicUuids.BatteryLevel))
            {
                try
                {
                    // battery level is encoded as a percentage value in the first byte according to
                    // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.battery_level.xml
                    return "Battery Level: " + data[0].ToString() + "%";
                }
                catch (ArgumentException)
                {
                    return "Battery Level: (unable to parse)";
                }
            }
            // This is our custom calc service Result UUID. Format it like an Int
            else if (selectedCharacteristic.Uuid.Equals(Constants.ResultCharacteristicUuid))
            {
                return BitConverter.ToInt32(data, 0).ToString();
            }
            // No guarantees on if a characteristic is registered for notifications.
            else if (registeredCharacteristic != null)
            {
                // This is our custom calc service Result UUID. Format it like an Int
                if (registeredCharacteristic.Uuid.Equals(Constants.ResultCharacteristicUuid))
                {
                    return BitConverter.ToInt32(data, 0).ToString();
                }
            }
            else
            {
                try
                {
                    return "Unknown format: " + Encoding.UTF8.GetString(data);
                }
                catch (ArgumentException)
                {
                    return "Unknown format";
                }
            }
        }
        else
        {
            return "Empty data received";
        }
        return "Unknown format";
    }
        ///////// END OF UPDATE //////


 private async void TrySend(string data)

    {
        // Create the StreamSocket and establish a connection to the echo server.

        StreamSocket socket = new StreamSocket();
        try
        {
            var streamSocket = new Windows.Networking.Sockets.StreamSocket();
            {
                //The server hostname that we will be establishing a connection to. In this example, the server and client are in the same process.
                var hostName = new Windows.Networking.HostName("127.0.0.1");
                await streamSocket.ConnectAsync((new Windows.Networking.HostName("127.0.0.1")), "9999");

                // Send a request to the echo server.
                using (Stream outputStream = streamSocket.OutputStream.AsStreamForWrite())
                {
                    using (var streamWriter = new StreamWriter(outputStream))
                    {
                        while (true)
                        {
                            await streamWriter.WriteLineAsync(data);
                            await streamWriter.FlushAsync();
                        }

                        //await streamWriter.WriteLineAsync(data);
                        //await streamWriter.FlushAsync();
                    }
                }
            }
        }
        catch (Exception)
        {
        }
    }

这是我接收数据的 TCP 服务器代码:

 public class EchoServer {
public static void Main() {
    TcpListener listener = null;

    try
    {
        listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 9999);
        listener.Start();
        Console.WriteLine("TCP Server Has Started....");
        while (true)
        {
            Console.WriteLine("                                           ");
            Console.WriteLine("Waiting for incoming client connections....");
            Console.WriteLine("                                           ");
            Console.WriteLine("A message will display below once the client starts and establishes a connection ");
            TcpClient client = listener.AcceptTcpClient();
            Console.WriteLine("                                              ");
            Console.WriteLine("Okay, Accepting Client connection now");
            Console.WriteLine("                                       ");
            Console.WriteLine("Accepted new client connection.....");
            StreamReader reader = new StreamReader(client.GetStream());
            StreamWriter writer = new StreamWriter(client.GetStream());
            string s = string.Empty;
            while (!(s = reader.ReadLine()).Equals("Exit") || (s == null)) {
                Console.WriteLine("From client -> " + s);
                writer.WriteLine("From server -> " + s);
                writer.Flush();
            }
            reader.Close();
            writer.Close();
            client.Close();
        }



    } catch (Exception e)
    {
        Console.WriteLine(e);

    } finally
    {
        if (listener != null)
        {
            listener.Stop();
        }
    }

  }
}

现在,我要获取的数据是心率,它每两秒变化一次。然而,在 TCP 服务器上,我只获得了心率的第一个记录值,并且它不断重复而不是获得新的值。

我在 Whosebug 上看到了类似的 post:

有人建议使用我在代码中看到的 while 循环。 关于我该怎么做,还有其他建议吗?

谢谢

while (true)
{
    await streamWriter.WriteLineAsync(data);
    await streamWriter.FlushAsync();
}

while(true) 将不断重复,这意味着它将始终以其当前值发送 'data'。这就是导致您出现问题的原因。

在我看来,您应该在 'TrySend' 方法之外保持与 TCP 服务器的连接打开,并且仅使用此方法发送数据。这样你就不需要使用这个循环了。

编辑:

试试这个:

private async void CharacteristicReadButton_Click()
    {
    while(true)
    {
            // BT_Code: Read the actual value from the device by using Uncached.
            GattReadResult result = await selectedCharacteristic.ReadValueAsync(BluetoothCacheMode.Uncached);
            if (result.Status == GattCommunicationStatus.Success)
            {


                string formattedResult = FormatValueByPresentation(result.Value, presentationFormat);
                rootPage.NotifyUser($"Read result: {formattedResult}", NotifyType.StatusMessage);

                //string formattedResult = FormatValueByPresentation(result.Value, presentationFormat);
                //rootPage.NotifyUser($"Read result: {formattedResult}", NotifyType.StatusMessage);
            }
            else
            {
                rootPage.NotifyUser($"Read failed: {result.Status}", NotifyType.ErrorMessage);
            }
        }
    }