尽管所有数据包都到达(Wireshark),但 .Net UDP 数据包丢失 - ReceiveBuffer 不是问题 [英] .Net UDP packet loss though all packets arrive (Wireshark) - ReceiveBuffer not the issue

查看:120
本文介绍了尽管所有数据包都到达(Wireshark),但 .Net UDP 数据包丢失 - ReceiveBuffer 不是问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这与 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆