첫 번째 배경. 이더넷 케이블을 통해 내 앱이 연결되어있는 카메라를 가지고 있으며 명령을 기반으로 작업을 수행하고 명령을 보내면 응답합니다.스트림에서의 빠른 패킷 처리
예를 들어 카메라 트리거 명령을 사용합니다. 'T1'을 보내면 카메라가 사진을 찍습니다. 모든 명령은 내가이
(문자) 0x02T1 (문자) 0x03으로
모양을 보낼 전체 패킷 수 있도록 시작과 팩의 끝을 표시하기 위해 시작과 끝 문자를 사용하여 시작으로 (문자)는 0x02 팩의 끝으로 (char) 0x03.
카메라가 사진을 찍은 다음 동일한 명령을 보내면 완료되었다고 말합니다. 또한 사진을 촬영할 때 일부 데이터를 다시 보내도록 카메라를 설정할 수 있습니다. 제 경우에는 카메라를 몇 가지 영역을 검사하고 검사에서 일부 값을 원합니다.
그래서 카메라의 반환은 'T1'과 같이 될 것이라고 다음 문제에
을 '1,1,500,20,300'을 말한다. 나는 통신을 위해 TcpClient
과 NetworkStream
을 사용하고 있지만 수신 측에서 패킷을 처리하는 데 어려움을 겪고있다. 다양한 방법을 시도했지만 속도가 느려지거나 모든 데이터를 가져올 수 있다고 보장하지 않습니다.
먼저 모든 데이터를 읽고 모든 데이터가 있는지 확인해야합니다.
둘째, 데이터를 처리하고 패킷으로 분할하여 가능한 한 빨리 처리 할 수있는 무언가가 필요합니다.
이것은 내가 시도한 한 가지 방법 일 뿐이며 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 개의 문자를받는다면, 항상 복수 수신으로 나뉘어집니다. –