原始以太网广播

时间:2011-07-07 11:41:14

标签: networking broadcast ethernet wdk ndis

我下载了WinDDK并使用ndisprot 5x从我的用户应用程序广播原始以太网数据包,指定目标MAC全部为0xff,在大型和重复数据集上,它似乎效率不高。

目前效果很好的是环回 - 指定目标和源MAC作为我自己的我需要的速度,但数据包永远不会离开我的网卡。

也许我错过了一些ndis驱动程序选项并等待使用此示例MS驱动程序完成广播?我想要的只是要广播到网络的数据包,我并不关心交付状态,并希望尽快摆脱它。

只有2分的系统会帮助吗?我不确定是什么导致了延迟。

1 个答案:

答案 0 :(得分:1)

在内核模式下无法消除发送完成路径。原因是网卡正在忙于从内存中读取字节,直到它最终发出发送完成。如果您在重新使用数据包之前没有等待发送完成,那么网卡就没有机会读取完整的数据包。你最终会发送损坏的数据。

但是,使用NDISPROT库存样本发送大量数据时,效率很低是正确的。问题是NDISPROT的usermode示例应用程序将数据写入kernelmode 同步。这意味着您的线程开始写入(发送数据包),然后阻塞直到写入(发送数据包)完成。 (样本效率低下,因为NDISPROT示例的目的是说明如何在内核模式中与NDIS进行互操作,而不是说明用户内核通信的复杂技术。)

通过使用多种技术之一同时发布多个数据,您可以大大提高速度:

  1. 使用多线程。做你现在正在做的事情,除了并行地在多个线程上做。这很容易设置,但它不能很好地扩展(扩展到10倍流量,你需要10个线程,然后你开始受到缓存问题的伤害)。另外,如果必须按顺序发送数据集,则需要进行大量复杂的同步,以确保线程按顺序发出请求。

  2. 使用WriteFile和OVERLAPPED数据结构的异步调用。这需要您在usermode应用程序上进行一些重组。 (幸运的是,你不需要触摸内核驱动程序,因为那已经支持了这一点)。使用OVERLAPPED写入,您可以从单个线程发出多个同时写入,然后在任何(或全部)完成时收到通知。如果您对重叠设计足够小心,您应该能够轻松填充100Mbps网络链接。

  3. 更明确地说,这就是你今天所拥有的:

    Your app           NDISPROT driver         Network card         The network
    ---------------------------------------------------------------------------------
      WriteFile
       .      \-------> NdisProtWrite
       .                            \-------> NdisSendPackets
       .                                            |
       .                                   (copy packet payload
       .                                    from system RAM to
       .                                    network card's buffer)
       .                                            |
       .                                            |---------------> Start sending
       .             NdisProtSendComplete <---------|                      .
      WriteFile <----/                              |                      .
       returns                                      |<--------------- Finish sending
    

    如您所见,您的用户模式应用程序在网卡将数据包有效负载从RAM复制到NIC硬件的整个时间内都停留在WriteFile中。相反,如果你使用异步写入kernelmode,你最终会得到这个:

    Your app           NDISPROT driver         Network card         The network
    ---------------------------------------------------------------------------------
      WriteFile
       .      \-------> NdisProtWrite
       .               |            \-------> NdisSendPackets
      WriteFile <------/                           |
       returns                              (copy packet payload
                                            from system RAM to
                                            network card's buffer)
                                                    |
                                                    |---------------> Start sending
                     NdisProtSendComplete <---------|                      .
      Async write <--/                              |                      .
       completes                                    |<--------------- Finish sending
    

    在此设置中,WriteFile返回的速度更快,因此当NIC仍在读取第一个数据包时,您有机会排队另一个数据包(或10)。您可以使用任何常用的OVERLAPPED技术来确定写入(发送数据包)何时完成,并且您可以重用数据缓冲区。

    要开始使用异步I / O,请从this documentation开始。 (糟糕,看起来他们的图表与我真棒的ASCII艺术相比旋转了90°......)。