【问题标题】:Socket exception on Hyper-V machineHyper-V 机器上的套接字异常
【发布时间】:2013-02-22 22:47:22
【问题描述】:

最近,我们的整个 QA 环境从 VMWare 迁移到了 Hyper-V 虚拟机。

我们的一个应用程序以每秒 20K 个数据包的速率将 UDP 数据包发送到多播云。

虽然这在 VMWare 环境中运行良好,但 Hyper-V 使应用程序在工作几分钟后引发以下异常:

System.Net.Sockets.SocketException (0x80004005): An invalid argument was supplied
   at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)

在将套接字的发送缓冲区大小定义为 1,000,000 字节时,我还设法立即模拟了这个问题。

我该如何解决这个问题?

更新 1:这是发生异常后来自事件查看器的日志条目:

Faulting application name: Agent.exe, version: 1.0.12.7366, time stamp: 0x51389f69
Faulting module name: KERNELBASE.dll, version: 6.1.7601.18015, time stamp: 0x50b83c8a
Exception code: 0xe0434352
Fault offset: 0x0000c41f
Faulting process id: 0xaf0
Faulting application start time: 0x01ce1b4ce509dc7a
Faulting application path: C:\Users\DevUser\Desktop\QA\Agent.exe
Faulting module path: C:\Windows\syswow64\KERNELBASE.dll
Report Id: d2b45dce-8740-11e2-86f9-00155d022804

UPDATE 2:UDP 数据包大小为 100-200 字节。

更新 3:这是有问题的代码:

    m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    m_socket.Ttl = 1;

    if (GetRawParameter("send") != null)
    {
      Log("Starting sender...");

      StartSender();
    }

    ...snip...

private static void StartSender()
{
  m_lastPacketNumber = 0;

  m_socket.Connect(new IPEndPoint(m_ipAddress, m_port));

  if (m_bufferSize > 0)
    m_socket.SetSocketOption(
      SocketOptionLevel.Socket, SocketOptionName.SendBuffer, m_bufferSize);

  byte[] dataPad = null;

  if (m_packetSize > 8)
  {
    dataPad = new byte[m_packetSize - sizeof(long)];

    for (int i = 0; i < dataPad.Length; i++)
    {
      dataPad[i] = 0xFF;
    }
  }

  while (true)
  {
    Log("Sending data...");

    for (int i = 0; i < m_packetsPerSec; i++)
    {
      var data = BitConverter.GetBytes(m_lastPacketNumber.Value);

      if (dataPad != null)
        data = data.Concat(dataPad).ToArray();

      if (m_packetDump != null)
        m_packetDump.Add(m_lastPacketNumber.Value);

      m_socket.Send(data);

      if (m_usePerformanceCounters)
        IncreaseSendCounters(1);

      m_lastPacketNumber++;
    }

    Log(m_lastPacketNumber + " packets sent.");

    Thread.Sleep(1000);
  }
}

更新 4:当我尝试每秒发送 100K 个数据包时,失败的 Send() 似乎发生在 #14156 或 #32485 或 #25412 数据包(不是第一个!)上。

【问题讨论】:

  • ErrorCode = 10022, SocketErrorCode = InvalidArgument.
  • 当然,当您尝试发送这么大的数据包时会出现错误。您可以发送的最大 UDP 数据包约为 64K 字节。例如,请参阅stackoverflow.com/q/1098897/56778
  • 我指的是您的代码传递给System.Net.Sockets.Socket.Send() 的参数。或者,如果您不直接调用它,则在抛出异常之前 调用的最后一个 .NET 框架函数的名称和参数。
  • data.length = 100,Win32Api调用出现异常,返回上述错误码。
  • 我的测试应用程序只使用一个线程 - 这里没有问题。

标签: c# udp winsock multicast hyper-v


【解决方案1】:

您能否“卷起”这些数据包,以便发送更少的大尺寸数据包……然后在另一边展开它们? 20k 数据包/秒是很多 sendto 的。

【讨论】:

  • 我不能在发送数据之前延迟或缓冲数据。实际要求是 100K,实际使用 VMWare 机器即可。
猜你喜欢
  • 1970-01-01
  • 2021-10-21
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多