第一个背景。我有一个相机,我的应用程序通过以太网电缆连接到它,它根据我发送的命令执行操作,并返回命令响应。
如果我以相机触发命令为例。 如果我将相机发送到T1'相机将会拍照。所有命令都使用开始和结束字符来标记包的开始和结束,因此我发送的完整数据包将如下所示
(炭)0x02T1(炭)0×03
以(char)0x02作为数据包的开头,(char)0x03作为包的结尾。
然后,相机将拍摄照片并发回相同的命令,说它已完成。您还可以将相机设置为在拍摄照片时发回一些数据。在我的情况下,我让相机检查几个区域,我想要检查一些值。所以相机的回归就像是' T1'然后说' 1,1,500,20,300'
关于问题。我正在使用`function AnticipatedSyncFunction(){
var ret;
setTimeout(function(){
var startdate = new Date()
ret = "hello" + startdate;
},3000);
while(ret === undefined) {
require('deasync').runLoopOnce();
}
return ret;
}
var output = AnticipatedSyncFunction();
var startdate = new Date()
console.log(startdate)
console.log("output="+output);`
和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
TcpClient.GetStream()
答案 0 :(得分:0)
我制作了一些伪代码,我没有测试过,但它可能会给你一个方向。 这不能是静态的
char[] _buffer = new char[4 * 1024 * 1024];
int currentPosition;
public bool ReadNext(StreamReader reader, char delimiter, out string value)
{
// read as many chars from the stream.
int charsRead = reader.ReadBlock(_buffer, currentPosition, _buffer.Length - currentPosition);
// keep track of the current position.
currentPosition += charsRead;
// find the first delimiter.
for (int i = 0; i < currentPosition; i++)
{
if (_buffer[i] == delimiter)
{
// a complete packet was found, copy it to a string.
value = new string(_buffer, 0, i);
// move the rest of the data back to the start of the buffer.
Array.Copy(_buffer, i, _buffer, 0, _buffer.Length - i);
// decrease the current position also.
currentPosition -= i;
// return true because you have data.
return true;
}
}
// no complete packet was found.
value = String.Empty;
return false;
}
用法:
string data;
while(true)
{
if(ReadNext(reader, (char)0x03, out data))
MessageBox.Show(data);
}
就像我说未经测试一样,这只是一个脑力......你可能需要添加对数据包开始的检查。