C# 从TcpClient的流中读取所有数据
我在我的工厂里用一台新机器工作,这台机器是通过PC控制的。电流卡在通过以太网连接的摄像系统上 这是我打开连接的代码C# 从TcpClient的流中读取所有数据,c#,stream,tcpclient,C#,Stream,Tcpclient,我在我的工厂里用一台新机器工作,这台机器是通过PC控制的。电流卡在通过以太网连接的摄像系统上 这是我打开连接的代码 TcpClient client; NetworkStream stream; public bool OpenConnection() { client = new TcpClient(); try { //Camera.Open(); client.Connect("192.168.0.10", 8500); strea
TcpClient client;
NetworkStream stream;
public bool OpenConnection()
{
client = new TcpClient();
try
{
//Camera.Open();
client.Connect("192.168.0.10", 8500);
stream = client.GetStream();
}
catch (Exception ex)
{
return false;
}
return true;
}
到目前为止还不错。一旦连接打开,我就会向摄像机索取一些信息
我使用的消息格式有STX(0x02)来表示消息的开始,ETX(0x03)作为消息的结束
char StartOfPacket = (char)0x02;
char EndOfPacket= (char)0x03;
public bool RetrieveDigits(out string Digits)
{
// Send the trigger cammand to the vision system
Digits = "";
bool EverythingOK = true;
string DataToSend = StartOfPacket + "T1" + EndOfPacket;
byte[] buff = Encoding.ASCII.GetBytes(DataToSend);
if (LogCameraEvent != null)
LogCameraEvent(">> " + DataToSend);
try
{
stream.Write(buff, 0, buff.Length);
}
catch (Exception ex)
{
Logging.Instance.LogExceptionToFile(MethodBase.GetCurrentMethod(), ex);
EverythingOK = false;
}
Thread.Sleep(100);
byte[] buffer;
if (EverythingOK)
{
// Check the response
buffer = ReadCamera(10);
// Process the packets
string[] packets = ProcessPackets(buffer);
if (packets != null)
{
if (packets.Length > 0)
{
bool TriggerFound = false;
for (int i = 0; i < packets.Length; i++)
{
if (packets[i] == "T1")
{
TriggerFound = true;
continue;
}
else if (TriggerFound)
{
// If we are here then we should now be the data that was requested
if (string.IsNullOrEmpty(packets[i]))
{
Digits = packets[i-1]; // previous packet may have data from previous trigger. Need to look into why this happens.
}
else
Digits = packets[i];
EverythingOK = true;
break;
}
else
EverythingOK = false;
}
}
else
{
Console.WriteLine("No Packets Recieved");
EverythingOK = false;
}
}
else
{
Console.WriteLine("No Packets Recieved");
EverythingOK = false;
}
}
return EverythingOK;
}
所以我看到了摄像机发出的信息。我确认电脑已使用wire shark接收到数据。
现在在RetrieveDigits
方法中,您可以看到我处理接收到的数据包,循环遍历数据包直到找到“T1”,然后假设下一个数据包就是我要查找的数据,并将数字设置为该值。
我发现,有时当我运行应用程序时,我会看到Digits
被设置为“”。
我还发现,有时我收到的数据将是“AA”然后是“T1”,而不是“T1”然后是“AA”。我怀疑的是,当它从后到前的时候,“AA”实际上是来自于之前从摄像机发送的数据,并且由于某种原因,它在从流中读取时被遗漏了
在我读取数据流之前,任何关于为什么会发生这种情况的想法都是错误的
编辑:
修改了ReadCamera
代码以处理数据包,每次读取1个字节
private string[] ReadCamera(int ExpectedLength, int ExpectedPackets)
{
List<string> Packets = new List<string>();
bool StartFound = false;
StringBuilder sb = new StringBuilder();
if(ExpectedLength < 1)
{
ExpectedLength = 100;
}
byte[] Buffer = new byte[ExpectedLength];
int read = 0;
while (true)
{
read += stream.Read(Buffer, read, 1);
// Check to see if the byte read is the start of a packet
if (Buffer[read - 1] == StartOfPacket)
{
StartFound = true;
}
else if (StartFound)
{
// Check to see if the byte read is the end of a packet
if (Buffer[read - 1] == EndOfPacket)
{
Packets.Add(sb.ToString());
sb.Clear();
StartFound = false;
if (Packets.Count == ExpectedPackets)
break;
}
else
{
sb.Append(Encoding.ASCII.GetChars(Buffer, read - 1, 1));
}
}
}
// For Debuggin purposes
foreach(string s in Packets)
if (LogCameraEvent != null)
LogCameraEvent("<< " + s);
return Packets.ToArray();
}
虽然我怀疑这是否相关,但我建议使用使用块和client=new TcpClient()
和stream=client.GetStream()代码>因为它们实现IDisposable.DataAvailable几乎总是一个错误。它不会做你认为它会做的事。完全从代码中删除它。@BradM感谢您的评论,通常我会这样做并建议这样做,但在我的应用程序中,我会轮询相机系统,所以当不再需要时,我会手动关闭流。@usr感谢您提供的信息,您知道另一种方法吗?根本无法判断另一方何时完成发送,因为它随时可能发送另一个字节。您可以一直读取,直到获得零字节(流结束),或者直到您可以从读取的字节中检测到消息已完成。
>>[STX]T1[ETX]
<<[STX]T1[ETX][STX]AA[ETX]
private string[] ReadCamera(int ExpectedLength, int ExpectedPackets)
{
List<string> Packets = new List<string>();
bool StartFound = false;
StringBuilder sb = new StringBuilder();
if(ExpectedLength < 1)
{
ExpectedLength = 100;
}
byte[] Buffer = new byte[ExpectedLength];
int read = 0;
while (true)
{
read += stream.Read(Buffer, read, 1);
// Check to see if the byte read is the start of a packet
if (Buffer[read - 1] == StartOfPacket)
{
StartFound = true;
}
else if (StartFound)
{
// Check to see if the byte read is the end of a packet
if (Buffer[read - 1] == EndOfPacket)
{
Packets.Add(sb.ToString());
sb.Clear();
StartFound = false;
if (Packets.Count == ExpectedPackets)
break;
}
else
{
sb.Append(Encoding.ASCII.GetChars(Buffer, read - 1, 1));
}
}
}
// For Debuggin purposes
foreach(string s in Packets)
if (LogCameraEvent != null)
LogCameraEvent("<< " + s);
return Packets.ToArray();
}
// Check the response
string[] packets = ReadCamera(10,2);
// Process the packets
//string[] packets = ProcessPackets(buffer);