C#UDP-可以告诉窗口在一定时间后丢弃数据包
本文关键字:定时间 数据包 窗口 C#UDP- | 更新日期: 2023-09-27 18:29:48
我有一个非常高速率的UDP应用程序,我对这里的具体基础有点好奇。我使用的是c#异步方法,在EndReceive上,我将工作放在一个新线程上,然后调用BeginReceive。
据我所知,即使我目前处于EndReceive和BeginReceive之间的代码中,windows仍在接受该端口上的UDP数据包,每当我再次调用BeginReceives时,下一个数据包就会从堆栈中取出。
假设这都是真的(如果不是,请澄清)——我有可能在这些数据包上指定TTL吗?我需要向发送者发送一个响应,发送者被配置为在几秒钟后忽略响应。
感谢
当网络接口卡离线发送数据报时,操作系统会将其放入套接字的接收队列中。它在那里等待,直到您使用recvfrom()
系统调用或您选择的高级包装器读取它。
您可以通过对SO_RCVBUF
调用getsockopt()
来确定此缓冲区的大小。默认大小和最大大小因操作系统和版本而异。
网络数据报不携带任何定时信息,因此没有基于时间使其过期的内在方法。你选择如何进行实际上取决于你预计延迟的确切来源。
-
如果你关心从发送到处理的时间,那么你必须协调发送器和接收器之间的时钟,然后让发送器在每个数据报发送之前在它上加一个时间戳。这是了解事件之间实际时间的唯一方法。但请记住,网络延迟可能变化很大,因此简单地丢弃所有超过一定数量的数据包可能会导致丢弃所有数据包。
-
如果你只关心数据包接收到和处理之间的时间(忽略网络延迟),那么你需要有一个单独的线程在数据报到达时尽快读取数据报,记下它们的时间,并将它们存储在内部线程安全队列中。这是一项艰巨的工作,并且会带来大量的开销,因此您可能首先想了解处理延迟的原因。
-
如果数据包是以相当固定的速率发送的,并且/或者您关心的与其说是时间,不如说是积压了未处理的数据包,那么您可能只想减少接收队列的大小(
setsockopt()
和SO_RCVBUF
)。当接收队列已满时,任何到达的数据报都将被静默地丢弃。
当数据包太旧时,您需要丢弃数据包,这是特定于应用程序的,UDP无法提供(AFAIK)。Windows可能会"自动"为您接收和缓冲数据报,但它如何做到这一点是网络堆栈的实现细节。
我会把它分成两部分:
- 尽快接收消息并将其排队。
- 如果您想限制接收队列的大小,即使在这个阶段也可能开始丢弃最旧的消息
- 取消消息队列:
- 如果它们太老了,就把它们扔在地板上
- 以其他方式处理和确认它们
步骤2可能是平行的,以确保你的消费者跟上。
您可以在发送时指定TTL,但TTL会随着路由器的通过而递减,并且不是基于时间的。这不是你要找的领域。
因此,如果一个数据包的TTL为3,则在第一个路由器之后它变为2,在第二个路由器之后变为1,在第三个路由器处它变为0,在该路由器处数据包将被丢弃,而不向发送者发出任何通知。