原始以太网广播



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

目前工作的是环回-指定目标和源MAC作为我自己的,我得到所需的速度,但数据包永远不会离开我的网卡。

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

只有2个点的系统会有帮助吗?

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

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

您可以使用以下几种技术中的一种来同时发出多个数据块,从而大大加快此速度:

  1. 使用多线程。执行与现在相同的操作,只不过是在多个线程上并行执行。这很容易设置,但它不能很好地扩展(要扩展到10倍的流量,您需要10倍的线程,然后您开始在缓存问题上受到伤害)。另外,如果你的数据集必须按顺序发送,你需要一堆复杂的同步来确保线程按顺序发出请求。

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

更明确地说,这是你目前拥有的:

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

正如你所看到的,你的用户模式应用程序被卡在WriteFile的整个时间,网卡复制数据包有效载荷从RAM到网卡硬件。相反,如果您使用异步写入内核模式,您将得到如下结果:

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,请从本文档开始。(哎呀,看起来他们的图表被旋转了90度;

最新更新