我有一个非常高速率的UDP应用程序,我对这里的具体基础有点好奇。我正在使用c#异步方法,在EndReceive上,我将工作放在一个新线程上,然后调用BeginReceive。
据我所知,即使我目前处于EndReceive和BeginReceive之间的代码,Windows仍然接受此端口上的UDP数据包 - 每当我再次调用BeginReceive时,下一个将从堆栈中获取
假设这一切都是真的(如果没有,请让我直截了当) - 我可以在这些数据包上指定TTL吗?我需要向发件人发送响应,并且发件人配置为在几秒钟后忽略响应。
由于
答案 0 :(得分:4)
当网络接口卡通过线路传送数据报时,操作系统会将其放入插座的接收队列中。它会等到那里,直到您使用recvfrom()
系统调用或您选择的高级包装器读取它。
您可以通过为getsockopt()
调用SO_RCVBUF
来确定此缓冲区的大小。操作系统和版本的默认和最大大小大大。
网络数据报不包含任何计时信息,因此没有内在的方法可以根据时间使它们过期。您如何选择继续前进取决于您预计延迟的确切位置。
如果您担心从发送到处理的时间,那么您必须在发送方和接收方之间协调时钟,然后让发送方在发送之前在每个数据报中放置一个时间戳。这是了解事件之间实际时间的唯一方法。但请记住,网络延迟可能会有很大差异,因此简单地丢弃所有早于某些数据包的数据包可能会导致丢弃所有数据包。
如果您只关注收到数据包和处理数据包之间的时间(忽略网络延迟),那么您需要让一个单独的线程尽快读取数据报,注意他们的时间,并将它们存储在一个内部的,线程安全的队列中。这需要大量工作,并且会带来很大的开销,因此您可能首先要检查处理延迟的原因。
如果数据包以相当固定的速率发送和/或您关心的时间不是因为积压了未处理的数据包,那么您可能只想减小接收队列的大小( setsockopt()
与SO_RCVBUF
)。当接收队列已满时,任何到达的数据报都将被静默丢弃。
答案 1 :(得分:1)
您需要在数据包过时时丢弃数据包是特定于应用程序的,而且(AFAIK)不是UDP可以为您提供的。 Windows可能会“自动”为您接收和缓冲数据报,但它如何做到这一点是网络堆栈的实现细节。
我把它分成两部分:
第2步可能会并行化,以确保您的消费者跟上。
答案 2 :(得分:1)
您可以在发送时指定TTL,但TTL会在每个路由器通过时递减,并且不是基于时间的。这不是您正在寻找的领域。
因此,如果数据包的TTL为3,则在第一个路由器之后变为2,在第二个路由器之后变为1,在第三个路由器变为0,而数据包将被丢弃,而不向发送者发送任何通知。