最初の背景。私は、私のアプリがイーサネットケーブルを介して接続されているカメラを持っていて、それは送信したコマンドに基づいて操作を実行し、コマンドで返信します。ストリームからの高速パケット処理
例としてカメラのトリガーコマンドを使用します。 「T1」を送信すると、カメラで写真が撮影されます。すべてのコマンドは、スタートとして、私が送っフルパケットが(文字)が0x02でこの
(CHAR)0x02T1(文字)0x03の
のようになりますので、パックの開始と終了をマークするために、開始と終了文字を使用しますパケットの(char)0x03をパックの最後とします。
カメラが写真を撮影し、同じコマンドを送り返して終了します。また、画像を撮影したときにデータを戻すようにカメラを設定することもできます。私の場合、私はカメラがいくつかの領域を検査しており、検査からいくつかの値が必要です。
ので、カメラのリターンは、「T1」のようなものにし、問題への「1,1,500,20,300」
を言うでしょう。私は通信のためにTcpClient
とNetworkStream
を使用していますが、私は受信側でパケットを処理するのに苦労しています。私は様々な方法を試しましたが、遅くなったり、すべてのデータを取得する保証はありません。
まず、すべてのデータを読み、すべてのデータがあることを確認する必要があります。
第2に、データを処理してパケットに分割し、可能な限り高速に処理できるものが必要です。
これは私が試した1つの方法であり、StreamReaderExtensions
を作った人に全額のクレジットが送られます。私はどこかでここでそれを見つけたと確信しています。
internal static class StreamReaderExtensions
{
public static IEnumerable<string> ReadUntil(this StreamReader reader, string delimiter)
{
List<char> buffer = new List<char>();
CircularBuffer<char> delim_buffer = new CircularBuffer<char>(delimiter.Length);
while (reader.Peek() >= 0)
{
char c = (char)reader.Read();
delim_buffer.Enqueue(c);
if (delim_buffer.ToString() == delimiter)
{
if (buffer.Count > 0)
{
yield return new String(buffer.ToArray());
buffer.Clear();
}
continue;
}
buffer.Add(c);
}
}
private class CircularBuffer<T> : Queue<T>
{
private int _capacity;
public CircularBuffer(int capacity)
: base(capacity)
{
_capacity = capacity;
}
new public void Enqueue(T item)
{
if (base.Count == _capacity)
{
base.Dequeue();
}
base.Enqueue(item);
}
public override string ToString()
{
List<String> items = new List<string>();
foreach (var x in this)
{
items.Add(x.ToString());
};
return String.Join("", items);
}
}
}
と私の処理方法。 _stream
は
public static class Constants
{
public const char StartOfPacket = (char)0x02;
public const char EndOfPacket = (char)0x03;
}
private IEnumerable<string> ProcessResponse()
{
var streamReader = new StreamReader(_stream);
var packets = streamReader.ReadUntil(new string(new char[] {Constants.EndOfPacket}));
return packets;
}
あなたはcharごとに読んでください。大きなブロックを読み、受信したサイズを確認するだけです。区切り文字を見つけて解析されたブロックを削除するまでブロックを解析します。パケットが半分になるまで繰り返します。 –
@JeroenvanLangenハーフパケット? – Gaz83
より多くの受信/パケットでメッセージを分割することができます。これは、データグラムの代わりにストリームであるためです。当時は1文字しか受け取られていない場合は、常に複数の受信で分割されています。 –