首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何提高Java DatagramSocket的性能?

如何提高Java DatagramSocket的性能?
EN

Stack Overflow用户
提问于 2009-05-26 20:35:43
回答 9查看 8.1K关注 0票数 4

我正在使用Java类将DatagramSocket数据报发送到端点。数据报必须在60ms间隔内到达端点。

我发现DatagramSocket.Send通常需要1毫秒(接近2毫秒)来打包和发送不超过56字节的数据包。这会导致我的数据包以62毫秒的间隔传送,而不是以60毫秒的间隔传送。

这是在windows vista机器上。下面是我测量时间的方法:

代码语言:javascript
运行
复制
              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." );

有没有人有加快这一过程的提示或技巧?

EN

回答 9

Stack Overflow用户

发布于 2009-05-26 21:09:47

您可以使用Timer类来安排事件。

代码语言:javascript
运行
复制
    Timer timer = new Timer();
    TimerTask task = new TimerTask() {
        public void run() {
            //send packet here
        }};
    timer.scheduleAtFixedRate(task, 0, 60);

这将每隔60ms创建一个循环事件来执行"run“命令。在所有条件保持不变的情况下,数据包应该每60ms命中一次(尽管,第一个数据包将被延迟一定数量,并且垃圾收集/其他任务/等可能会稍微延迟这个数字)。

票数 6
EN

Stack Overflow用户

发布于 2009-05-26 20:47:35

您可以看到将数据从用户空间复制到内核空间所花费的时间。通过UDP、IP和以太网层发送数据需要更长的时间,而且数据报通过物理网络到达目的地可能需要不同的时间。

假设您的网络没有抖动(每个数据包传输时间的差异),并且您的进程以实时优先级运行,并且没有任何其他因素与其竞争CPU...

无论send()方法执行需要多长时间,都需要每隔60ms调用一次send。不能在两次调用之间等待60毫秒。您需要测量执行循环体(send()和其他任何内容)所需的时间,然后从60ms中减去它,以获得等待时间。

票数 4
EN

Stack Overflow用户

发布于 2009-05-27 20:09:13

使用计时器,正如James Van Huis所提到的那样。这样,你至少会得到正确的平均频率。

引用自javadoc:

如果执行由于任何原因(如垃圾收集或其他后台活动)而延迟,则将快速连续执行两次或更多次以“赶上”。从长远来看,执行频率将正好是指定时间段的倒数(假设Object.wait( long )下的系统时钟是准确的)。

另外,为了回答你实际但可能有点误导的问题:在我的机器上,重用一个实例DatagramPacket并只设置一个新的输出缓冲区,平均“大量”微秒。

代码语言:javascript
运行
复制
    datagram.setData(out);
    socket.send(datagram);

它稍微减少了gc上的负载,因此如果您正在以高速率发送,这可能是一个好主意。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/912623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档