代码之家  ›  专栏  ›  技术社区  ›  usr-local-ΕΨΗΕΛΩΝ

使udp在.net/mono中丢失的消息更少

  •  1
  • usr-local-ΕΨΗΕΛΩΝ  · 技术社区  · 14 年前

    我们目前正在为一个开源学术项目执行一些基准测试, Logbus-ng . 它基本上通过UDP(RFC5426)和TLS(RFC5425)实现了系统日志协议。

        UdpClient _client;
        IQueue<T>[] _byteQueues; //not really IQueue, but a special FIFO queue class that reduces overhead to the minimum
    
        private void ListenerLoop()
        {
            IPEndPoint remoteEndpoint = new IPEndPoint(IPAddress.Any, 0);
            while (_listen)
            {
                try
                {
                    byte[] payload = _client.Receive(ref remoteEndpoint);
    
                    _byteQueues[
                        (((Interlocked.Increment(ref _currentQueue))%WORKER_THREADS) + WORKER_THREADS)%WORKER_THREADS].
                        Enqueue(payload);
                }
                catch (SocketException)
                {
                }
                catch (Exception)
                {
                } //Really do nothing? Shouldn't we stop the service?
            }
        }
    

    try
    {
        Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
                                {
    #if !MONO
                                    //Related to Mono bug 643475
                                    ExclusiveAddressUse = true,
    #endif
                                };
    
        if (ReceiveBufferSize >= 0) clientSock.ReceiveBufferSize = ReceiveBufferSize;
        clientSock.Bind(localEp);
        _client = new UdpClient {Client = clientSock};
    }
    catch (SocketException ex)
    {
        throw new LogbusException("Cannot start UDP listener", ex);
    }
    

    /proc/net/udp lsof

    SVN

    3 回复  |  直到 9 年前
        1
  •  1
  •   Chris Taylor    14 年前

    receiveBufferSize确实会影响到UDP套接字(即udpclient),如果数据包丢失是由于缓冲区溢出,那么增加receiveBufferSize将有所帮助。

    请记住,如果数据速率太高,以至于您无法足够快地从缓冲区读取足够长的时间,那么即使是最大的缓冲区,也不可避免地会溢出。

    我已经在运行在Ubuntu上的mono 2.6.7上有效地使用了udpclient.client.receiveBufferSize,所以我相信mono的实现是好的,当然我还没有在mono 2.8上使用它。

    根据我的经验,以极高的速率向本地主机发送UDP数据包,可能会有一些数据包丢失,尽管我从未在现实世界应用程序中经历过这种数据包丢失。因此,您可能在这种方法上取得了一些成功。

    您还需要看看是否发生了数据包丢失,这可能是由于网络基础设施、数据包冲突、交换机可能因为交换机上的某些限制而丢弃数据包。

    简单地说,在使用UDP时,您需要准备好处理和预期数据包丢失。

        2
  •  0
  •   Syaiful Nizam Yahya    11 年前

    如果您使用的是UDP,则必须预期数据包丢失。数据包丢失的原因很多。对于您来说,最可能的原因是数据包在通道上的任何位置都被溢出。可能是你的开关,也可能是你的接收器。过度泛滥的原因是因为UDP没有任何类型的拥塞控制。TCP确实有拥塞控制(缓慢启动),这就是为什么在TCP中,它从不(理论上在理想环境下)过度泛滥的原因。

    采用TCP慢启动拥塞控制策略是防止UDP传输超淹没的有效方法。

    回答你直截了当的问题 1。不。请参阅TCP慢速启动算法。 2。很可能这不是一个错误。UDP就是这样设计的。这是有原因的,需要这样做。 三。不,代理没有帮助。 4。最简单的实现方法是在发送更多数据包之前等待接收器的确认(注意接收器已成功接收到数据包)。当然,这对防止由于其他原因造成的数据包丢失没有帮助。

        3
  •  0
  •   slowdog    9 年前

    显然,它也应该在mono中工作,但您知道该属性可能存在的bug吗?我是说,有人报告过病毒吗?(单2.8)

    显然,在3.2.7版本之前的mono中,设置socket-receive缓冲区的大小严重中断:它将被设置为随机值,而不是指定的大小,因此尝试增加缓冲区的大小实际上会使性能变差:-(

    https://github.com/mono/mono/commit/bbd4ee4181787189fbb1f8ba6364afdd982ae706