尽管所有数据包都到达(Wireshark),但 .Net UDP 数据包丢失 - ReceiveBuffer 不是问题 [英] .Net UDP packet loss though all packets arrive (Wireshark) - ReceiveBuffer not the issue
问题描述
这与 C# UDP packetloss 尽管所有数据包都到达 (WireShark) 是相同的问题,但我确实设置了 ReceiverBuffer
到 10MB,我还监视 Socket.Available
显示缓冲区甚至没有达到 200k 利用率.
This is the same question as C# UDP packetloss though all packets arrive (WireShark), except I do set ReceiverBuffer
to 10MB, and I also monitor Socket.Available
which shows the buffer doesn't even reach 200k utilization.
在一个简单的测试案例中,使用 tcpreplay 以 40Mbps 的速率发送相同的小(多播)UDP 数据包(净数据大小:137)25,000 次,通常并非所有数据包都到达我的程序,尽管所有数据包都到达了 Wireshark,我同时在那个盒子上运行.有时只丢失一个数据包,有时大约有十几个,有时更多.
In a simple test case, sending the same small (multicast) UDP packet (net data size: 137) 25,000 times using tcpreplay with at rate of 40Mbps, oftentimes not all packets arrive in my program, although all packets arrive in Wireshark, which I run at the same time on that box. Sometimes it's only one packet that's missing, sometimes it's about a dozen, sometimes more.
代码
static void Main()
{
int udpPacketsReceived = 0;
var bindAddress = IPAddress.Parse("192.168.20.54");
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.ReceiveBufferSize = 10485760; // 10M
socket.Bind(new IPEndPoint(bindAddress, 51001));
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.193.1.1")));
Console.WriteLine("Effective ReceiveBuffer size: " + socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer));
var t = new Thread(ipAndClient =>
{
var buffer = new byte[2000];
int maxAvail = 0;
while (true)
{
socket.Receive(buffer);
Interlocked.Increment(ref udpPacketsReceived);
var available = socket.Available;
if (available > maxAvail)
{
Console.WriteLine("available new max: " + available);
maxAvail = available;
}
}
});
t.Start();
int lastValue = -1;
while (true)
{
var newValue = Thread.VolatileRead(ref udpPacketsReceived);
if (newValue != lastValue)
{
Console.WriteLine("Total UDP packets received: {0}", newValue);
lastValue = newValue;
}
Thread.Sleep(1000);
}
}
示例输出
Effective ReceiveBuffer size: 10485760
Total UDP packets received: 0
available new max: 685
available new max: 3288
available new max: 3836
available new max: 6165
available new max: 8220
available new max: 10960
Total UDP packets received: 14307
available new max: 18632
available new max: 140425
available new max: 141521
available new max: 143439
Total UDP packets received: 24996
怎么了?
重要补充(事后证明这很重要,请参阅我自己的答案):我正在 VirtualBox 主机中的 Windows 客户机上运行,使用桥接"虚拟网卡.
Important addition (which proved crucial in hindsight, see my own answer): I'm running on a Windows guest in a VirtualBox host, using a "bridged" virtual network card.
推荐答案
Steffen Ullrich 的回答和评论引导我深入了解我的系统设置 - 在 VirtualBox 中运行的 Windows 8.1 - 我发现对于我的工作负载,最大在 50Mbps 和 20kpps 左右,我可以通过将虚拟网卡从桥接"更改为半虚拟化网络适配器 (virtio-net)".
Steffen Ullrich's answer and comments lead me to dig deeper into the setup of my system - Windows 8.1 running in a VirtualBox - and I found that for my workloads, which max at around 50Mbps and 20kpps, I could get rid of all packet drops by changing the virtual network card from "bridged" to "Paravirtualized network adapter (virtio-net)".
这需要在 Windows 客户机中安装网络驱动程序.驱动程序,可以通过 http://www.linux-kvm.org/page/下载WindowsGuestDrivers/Download_Drivers.获取二进制数字签名驱动程序的最简单方法是单击Fedora"链接,然后安装netkvm.inf",这是Red Hat VirtIO Ethernet Adapter 驱动程序,适用于您的操作系统.
This necessitates installing network drivers in the Windows guest. Drivers, which can be downloaded via http://www.linux-kvm.org/page/WindowsGuestDrivers/Download_Drivers. The easiest way to get binary, digitally signed drivers is to click the "Fedora" link on that page, and install "netkvm.inf", which is the Red Hat VirtIO Ethernet Adapter driver, for your OS.
这篇关于尽管所有数据包都到达(Wireshark),但 .Net UDP 数据包丢失 - ReceiveBuffer 不是问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!