发送多个非常小的数据包或更少的大数据包?

时间:2015-07-10 12:38:35

标签: java sockets network-programming

我目前正在开发一个简单的应用程序,可以跨插座传输屏幕截图。我通过实例化和使用Robot类来获取屏幕截图,如下所示:

private Robot robot;
public Robot getRobot(){
    if(robot == null){
        try{
            robot = new Robot();
        }catch(Exception e){}
    }
    return robot;
}

public BufferedImage screenshot(){
    return getRobot().createScreenCapture(getScreenRectangle());
}

public byte[] getBytes(BufferedImage image){
    byte[] data = null;
    try{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(img, "PNG", baos);
        data = baos.toByteArray();
        baos.close();
    }catch(IOException e){}
    return data;
}

然后我使用上面的getBytes方法将BufferedImage转换为字节数组,然后将其写入套接字输出流。图像平均为500KB。将这500KB分成5KB的较小片段会更高效吗,或者将它保存在30KB的较大块中会更好。我的主要目标是交付的速度和准确性。我也很感激为什么任何一种方式在这些方面比另一方更有效的理由。

3 个答案:

答案 0 :(得分:2)

网络数据包大小受所谓的MTU限制,您不能发送大于mtu的数据包。你可以从链接检查mtu并不是那么大(我相信1500字节是以太网更常见的MTU)。这是针对网络方面的;在java端,决定段大小可能取决于同时发送的图像数量(如果同时发送100个图像,则分配100个段)。

我的建议是尝试使用稍微小于MTU的段大小(我猜您使用的是TCP / IP,因此必须考虑TCP和IP标头大小)并查看会发生什么。

编辑:一些评论指出(正确)形成java透视图,MTU不会影响数据应该如何分块;这对于大于MTU的数据包来说是正确的,因为TCP / IP层以较小的单位打破了较大的数据块;但海报想知道是否有“最佳”缓冲区大小;响应是在MTU上,在java端增加缓冲区大小没有任何好处(用于网络传输)

答案 1 :(得分:2)

  

发送多个非常小的数据包或更少的大数据包?

在应用程序中,这是一个非常常见的问题,即QoS起着重要作用。我认为没有一个正确的答案,只有一个能更好地适应你的要求的实施。

您可能会考虑以下几个方面:

  • 较大的数据包减少了数据开销的百分比。
  • 当接收或发送数据(数据损坏)出错时,较大的数据包会产生更大的影响。
  • 应该将较小的数据包用于为用户提供更好响应的应用程序。
  • 在某些应用中,流量很重要且需要快速处理信息,而不是为每个帧发送整个图像,应使用适当的协议发送不同部分的图像。

答案 2 :(得分:0)

Melli在他们的答案中有充分的理由说明为什么您会选择更大或更小的数据包。您基本上是在通过吞吐量来提高响应能力。

我不同意没有正确答案;至少在这种情况下,我认为显然有一个更好的答案:如果您希望它尽快到达另一端,请一次发送!

  • 更少的系统调用来发送数据
  • 更少的开销,因为您发送的TCP数据包和冗余报头更少
  • 碎片是低级网络堆栈的责任,而不是您的应用程序
  • 生成的代码将更加简单