Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 连接网线后在UDP套接字中接收数据之前的长延迟_.net_Windows_Sockets_Udp - Fatal编程技术网

.net 连接网线后在UDP套接字中接收数据之前的长延迟

.net 连接网线后在UDP套接字中接收数据之前的长延迟,.net,windows,sockets,udp,.net,Windows,Sockets,Udp,设置的简要说明:主机A直接连接到主机B;两者在同一子网中都有固定的IPv4地址 主机A(Windows 10)每10毫秒向主机B在端口5001的固定IP地址发送一个400字节的UDP数据包(包含递增整数的有效负载) 主机B(Windows 7)运行一个简单的.NET测试程序,该程序打开UDP套接字,在端口5001绑定到0.0.0.0,并等待传入的UDP数据包 在主机B上启动测试程序时,将按如下方式创建套接字: byte[] rcvBuffer = new byte[16 * 1024]; Soc

设置的简要说明:主机A直接连接到主机B;两者在同一子网中都有固定的IPv4地址

主机A(Windows 10)每10毫秒向主机B在端口5001的固定IP地址发送一个400字节的UDP数据包(包含递增整数的有效负载)
主机B(Windows 7)运行一个简单的.NET测试程序,该程序打开UDP套接字,在端口5001绑定到0.0.0.0,并等待传入的UDP数据包

在主机B上启动测试程序时,将按如下方式创建套接字:

byte[] rcvBuffer = new byte[16 * 1024];
Socket udpSock;

private void Start()
{
   try
   {
      udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
      udpSock.Bind(new IPEndPoint(IPAddress.Any, 5001));
      udpSock.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveUdp), udpSock);
   }
   catch (Exception ex)
   {
      MessageBox.Show(ex.Message);

      if(udpSock != null)
      {
         try
         {
            udpSock.Close();
            udpSock = null;
         }
         catch { }
      }
   }
}
接收回调如下所示

private void OnReceiveUdp(IAsyncResult ar)
{
   Socket sock = ar.AsyncState as Socket;
   if (sock == null)
   {
      MessageBox.Show("Socket is null");
      return;
   }

   try
   {
      int nBytes = sock.EndReceive(ar);
      if (nBytes == 0)
      {
         MessageBox.Show("0 bytes received");
         return;
      }

      sock.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveUdp), sock);
   }
   catch (Exception ex)
   {
      MessageBox.Show(ex.Message);
   }
}
正常情况下,一切正常:没有数据包被丢弃,也没有明显的延迟

我们注意到,如果我们将电缆从主机B的NIC上拔下,将其分离几秒钟,然后重新插入(主机a一直在发送),UDP数据包将相对较快地再次出现在Wireshark中,但有时需要10秒钟或更长时间,直到主机B上的UDP套接字再次开始接收数据。它接收到的第一个数据也不是Wireshark捕获的第一个UDP数据包,但似乎许多数据包在突然再次传递到传输层之前被丢弃。之后一切又恢复正常了

有没有其他人观察到这种现象,或者知道是什么导致了这种相对较大的延迟

一些补充说明:

  • 延迟不是固定的;有时甚至根本没有耽搁。其他时间需要10秒或更长时间
  • 当网络适配器禁用所有协议/筛选器驱动程序(IPv4除外)时,该问题仍然存在
  • 我们首先在使用Windows内核套接字开发的内核模式驱动程序中观察到这种行为

我知道UDP意味着可能的数据包丢失,但我只是觉得奇怪,数据包确实到达网卡,但却没有到达网络堆栈…

如果“连接”被断开,主机B上的程序会做什么?如果该程序在一段时间内没有接收数据包,或者出现了某种错误,会发生什么?该程序不会实现任何超时;它打开套接字并使其保持打开状态(因此,在一段时间内不接收数据包时不会发生任何事情)。异常会被捕获并显示在消息框中,但在测试过程中实际上不会抛出异常。无论如何,如果没有异常,将很难帮助您。请花一些时间阅读,以及。我还建议您使用调试器来逐步检查调试器中的“B”接收代码,以了解它真正的功能。我添加了测试程序的代码(在主机B上运行的代码),如果“连接”被删除,那么主机B上的程序会做什么?如果该程序在一段时间内没有接收数据包,或者出现了某种错误,会发生什么?该程序不会实现任何超时;它打开套接字并使其保持打开状态(因此,在一段时间内不接收数据包时不会发生任何事情)。异常会被捕获并显示在消息框中,但在测试过程中实际上不会抛出异常。无论如何,如果没有异常,将很难帮助您。请花一些时间阅读,以及。我还建议您使用调试器来逐步检查调试器中的“B”接收代码,以了解它真正的功能。或者至少添加一些非常详细和健谈的日志。我添加了测试程序的代码(在主机B上运行的代码)