我正在使用C#
和32feet
(版本3.5)通过蓝牙(SPP)将250字节的块发送到我正在为其编写固件的嵌入式设备。
我正在使用以下代码设置我的连接:
var client = new BluetoothClient();
client.Encrypt = true;
client.Connect(bluetoothAddress, ServiceClassId);
NetworkStream stream = client.GetStream();
var writer = new BinaryWriter(stream);
我遇到了一个非常低吞吐量的问题,每个块需要大约100毫秒才能通过以下代码传输:
public void SendData(List<byte> data)
{
try
{
foreach (byte d in data)
{
writer.Write(d);
}
writer.Flush();
}
catch (Exception)
{
// The connection was lost
ConnectionCleanup();
}
}
将上面的代码块更改为下面的代码后,每个块在4 ms内发送。
try
{
writer.Write(data.ToArray());
writer.Flush();
}
catch (Exception)
{
// The connection was lost
ConnectionCleanup();
}
我很难理解这种“简单”代码更改如何对吞吐量产生如此大的影响。谁能帮我解释一下发生了什么?我想这与32feet的基本机制有关?
我来回更改了代码,结果每次都是一样的。传输的数据也是一样的。
我还直接从Windows连接到设备,然后在Realterm中打开COM端口以发送相同的数据。在这种情况下,我获得与使用writer.Write(data.ToArray())
类似的吞吐量。
我正在使用Microsoft Bluetooth Stack
。
答案 0 :(得分:2)
查看BinaryWriter
的{{3}},Write(byte)
调用基础流WriteByte(byte)
,同时Write(byte[])
调用Write(byte[], int, int)
}。进一步看,我们看到NetworkStream没有覆盖虚拟方法WriteByte,因此使用了reference source:
// Writes one byte from the stream by calling Write(byte[], int, int).
// This implementation does not perform well because it allocates a new
// byte[] each time you call it, and should be overridden by any
// subclass that maintains an internal buffer. Then, it can help perf
// significantly for people who are writing one byte at a time.
public virtual void WriteByte(byte value)
{
byte[] oneByteArray = new byte[1];
oneByteArray[0] = value;
Write(oneByteArray, 0, 1);
}
此外,NetworkStream
没有内部缓冲区,它只是将Write调用传递给基础Socket
。您在第一种情况下进行250次网络呼叫,在第二种情况下进行1次,因此性能差异的原因应该是显而易见的。