我正在使用Java类将DatagramSocket数据报发送到端点。数据报必须在60ms间隔内到达端点。
我发现DatagramSocket.Send通常需要1毫秒(接近2毫秒)来打包和发送不超过56字节的数据包。这会导致我的数据包以62毫秒的间隔传送,而不是以60毫秒的间隔传送。
这是在windows vista机器上。下面是我测量时间的方法:
DatagramPacket d = new DatagramPacket(out, out.length, address, port);
long nanoTime = System.nanoTime();
socket.send(d);
long diff = System.nanoTime() - nanoTime;
System.out.println( out.length + " in " + diff + "ms." );有没有人有加快这一过程的提示或技巧?
发布于 2009-05-26 21:09:47
您可以使用Timer类来安排事件。
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
//send packet here
}};
timer.scheduleAtFixedRate(task, 0, 60);这将每隔60ms创建一个循环事件来执行"run“命令。在所有条件保持不变的情况下,数据包应该每60ms命中一次(尽管,第一个数据包将被延迟一定数量,并且垃圾收集/其他任务/等可能会稍微延迟这个数字)。
发布于 2009-05-26 20:47:35
您可以看到将数据从用户空间复制到内核空间所花费的时间。通过UDP、IP和以太网层发送数据需要更长的时间,而且数据报通过物理网络到达目的地可能需要不同的时间。
假设您的网络没有抖动(每个数据包传输时间的差异),并且您的进程以实时优先级运行,并且没有任何其他因素与其竞争CPU...
无论send()方法执行需要多长时间,都需要每隔60ms调用一次send。不能在两次调用之间等待60毫秒。您需要测量执行循环体(send()和其他任何内容)所需的时间,然后从60ms中减去它,以获得等待时间。
发布于 2009-05-27 20:09:13
使用计时器,正如James Van Huis所提到的那样。这样,你至少会得到正确的平均频率。
引用自javadoc:
如果执行由于任何原因(如垃圾收集或其他后台活动)而延迟,则将快速连续执行两次或更多次以“赶上”。从长远来看,执行频率将正好是指定时间段的倒数(假设Object.wait( long )下的系统时钟是准确的)。
另外,为了回答你实际但可能有点误导的问题:在我的机器上,重用一个实例DatagramPacket并只设置一个新的输出缓冲区,平均“大量”微秒。
datagram.setData(out);
socket.send(datagram);它稍微减少了gc上的负载,因此如果您正在以高速率发送,这可能是一个好主意。
https://stackoverflow.com/questions/912623
复制相似问题