我在.Net / C#中编写了一些代码,用于通过以太网与某些工厂设备进行通信。我首先指定一个处理程序:
_TCPConn.BeginReceive(
_StateObject.sBuffer, 0, _StateObject.sBuffer.Length, SocketFlags.None,
new AsyncCallback(Socket_DataArrival), _StateObject);
然后在我的处理程序中,首先,我做一个 EndReceive ,然后我将数据从套接字的缓冲区传输到我自己的输入缓冲区以便稍后进行进一步处理,我记录一些东西,然后我做一个 BeginReceive 来重新开始,我退出处理程序。所以...
....
StateObject stateObject = (StateObject)ar.AsyncState;
int bytesReceived = stateObject.sSocket.EndReceive(ar);
// transfer bytes, log stuff, then reenable receive and leave . . .
_TCPConn.BeginReceive( _StateObject.sBuffer, 0,
_StateObject.sBuffer.Length, SocketFlags.None,
new AsyncCallback(Socket_DataArrival), _StateObject);
return;
这在大多数情况下工作正常,但如果工厂设备发送2个数据包靠近在一起就会失败。这是一个Wireshark(网络嗅探器)输出。第一列是前一个数据包的时间差,单位为微秒(是的,“微”,而不是“毫”)
002397 10.1.1.116 10.1.2.11 TCP .... Len=6
000024 10.1.1.116 10.1.2.11 TCP .... Len=9
当发生这种情况时,第一个数据包似乎消失了 - 处理程序永远不会被调用6字节数据包,只有9字节数据包。我知道数据包已到达PC上,因为Wireshark会显示它。
但是如果我们在工厂设备中引入延迟,那么问题就不再是24微秒,而是10毫秒。不幸的是,这不是一个解决方案,因为世界各地的工厂安装了大量设备,我们无法改变。
有关如何调试和修复此问题的任何建议? 提前谢谢!
答案 0 :(得分:0)
你为什么要做EndReceive(ar)你应该继续接收。分别处理收到的数据包。你无需停止接收。