Наскоро цялата ни QA среда се премести от VMWare към Hyper-V виртуални машини.
Едно от нашите приложения изпраща UDP пакети към мултикаст облак със скорост от 20K пакета в секунда.
Въпреки че това работи перфектно в средата на 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
АКТУАЛИЗАЦИЯ 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: неуспешното изпращане () изглежда се случва на пакета #14156 или #32485 или #25412 (не първия!), когато се опитам да изпратя 100K пакети в секунда.
System.Net.Sockets.Socket.Send()
. Или ако не го извиквате директно, името и аргументите за последната функция на .NET framework, която направите извикате преди изключението да бъде хвърлено. - person Warren Young   schedule 09.03.2013Socket.Send(Buffer)
? Показването на някакъв код е полезно. В противен случай просто си играеш на глупаци с нас ... а аз имам по-добри неща за вършене. - person Jim Mischel   schedule 10.03.2013data.Length
, когато се обадите наSend
. Също така, пълно проследяване на стека, когато е хвърлено изключение. Подозирам обаче, че проблемът е някъде другаде в стека. Опитвам се да разбера защо това работи на VMWare, но не успява на Hyper-V. Може да обмислите изтегляне на източника на Framework от referencesource.microsoft.com/netframework.aspx и да го използвате да влезе вSocket.Send
, само за да видиш къде се проваля. - person Jim Mischel   schedule 10.03.2013