【发布时间】:2013-05-30 15:31:55
【问题描述】:
在我的 C# 应用程序中,我通过调用 Socket.SendTo 发送 UDP 消息可能高达每秒 10,000 次。我知道它有时无法跟上我发送的数量。有没有办法检查它已排队或积压发送的数据量(以字节为单位,或我调用SendTo 的次数等)?
我的理想解决方案是在套接字开始运行落后时丢弃非必要消息,并让重要消息由套接字排队,因此在我调用 SendTo 之前了解套接字状态会非常有帮助。
谢谢
【问题讨论】:
在我的 C# 应用程序中,我通过调用 Socket.SendTo 发送 UDP 消息可能高达每秒 10,000 次。我知道它有时无法跟上我发送的数量。有没有办法检查它已排队或积压发送的数据量(以字节为单位,或我调用SendTo 的次数等)?
我的理想解决方案是在套接字开始运行落后时丢弃非必要消息,并让重要消息由套接字排队,因此在我调用 SendTo 之前了解套接字状态会非常有帮助。
谢谢
【问题讨论】:
数据包可能在许多不同的地方排队,这样做并不可行:它们可能在套接字上、在某个 IP 堆栈中、在网络接口输出队列中等等......
即使您找到了一种在操作系统中查询适当队列的方法(这肯定是不可移植的),您也不会通过这样做真正解决您的问题。原因是,除非您实际发送消息的速度超过了网络接口可以处理的速度,否则瓶颈很可能在网络上的某个地方,在发送计算机之外。由于当今通用计算机上的许多网络接口都是 1Gbps,因此网络接口很可能能够像您发起数据包一样快地发送数据包。阻塞点可能是某处的以太网交换机或路由器,您无法通过查询队列找出该以太网交换机或路由器何时丢弃数据包,何时不丢弃。
【讨论】:
您想要做的问题是管理传出队列的是操作系统内核,而不是您的应用程序。使用 UDP 时,排队的情况会更少,因此数据包会在需要时被丢弃。
最好的办法是在命令行上使用netstat -s 来查看协议统计信息和丢包计数(Windows 可能有一些花哨的 API 可以从应用程序中查询相同的信息,但我不知道)。
找到您的主机和网络可以维持的可接受的消息速率,并在达到/超过时切换到“精简”输出。这需要一些记账,但可以通过时间戳的环形缓冲区轻松完成。
【讨论】: