3

I am currently working on a simple application that transfers screenshots across sockets. I get the screenshot by instantiating and using the Robot class as follows:

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;
}

I then use the getBytes method above to convert the BufferedImage to a byte array which is then written to the socket output stream. The image is an average of 500KB. Would it be more efficient to split this 500KB into smaller segments of say 5KB or would it be better to keep it in larger chunks of say 30KB. My main aim here is speed and accuracy of delivery. I would also appreciate any reasoning of why either way would be more effective in these terms that the other.

roeygol
  • 4,908
  • 9
  • 51
  • 88
rodit
  • 1,746
  • 2
  • 19
  • 33

3 Answers3

3

Send multiple very small packets or fewer large packets?

This is a very common question in apps that QoS play an important role. I think that there isnt a correct answer, only an implemetation that adapts better to your requeriments.

A few aspects that you might consider:

  • Bigger packets reduces de % of overhead over data.
  • Bigger packets has a bigger impact when there is an error at recieving or sending data (corrupted data).
  • Smaller packets should be used for an application that provides better response to user.
  • In some applications where the traffic is important and necessary to process information quickly, instead of sending the entire image for each frame, portions of the image varied should be sent, using appropriate protocols.
melli-182
  • 1,216
  • 3
  • 16
  • 29
2

The network packet size is limited by what is called MTU, you can't send a packet bigger than mtu. The mtu, as you can check from the link, is not that big (I believe 1500 bytes is the more common MTU for Ethernet). This is for the network side; on the java side deciding the segment size could depend on the number of images transmitted concurrently (if you send 100 image concurrently you have 100 segments allocated).

My suggestion is to try with a segment size slightly less that MTU (I guess you are using TCP/IP so you must consider TCP and IP header size) and see what happens.

Edit: some comments point out (correctly) that form the java perspective the MTU does not affect how the data should be chunked; this is true for packet bigger than MTU since the TCP/IP layer breaks larger chunks of data in smaller units; but the poster wants to know if there is a "best" buffer size; and the response is that over the MTU there is no benefit (for network transmission) in increasing the buffer size at the java side

Giovanni
  • 3,951
  • 2
  • 24
  • 30
  • I appreciate the help. Could you give me some guidance on the header size of each packet? – rodit Jul 10 '15 at 12:52
  • 1
    yes, you can look at this answer http://stackoverflow.com/questions/1846077/size-of-empty-udp-and-tcp-packet the sum of headers (ethernet + ip + tcp ) is about 64 byte – Giovanni Jul 10 '15 at 12:56
  • @rodit it's about 50-60 bytes and not something you can change. It's not a detail you should be worrying about unless your messages are close to this size. – Peter Lawrey Jul 10 '15 at 12:57
  • 1
    MTU is irrelevant from the perspective of Java. TCP provides stream oriented data transfer: just write into the stream of the socket and the socket will take care of buffering and sending data. – Mark Rotteveel Jul 10 '15 at 12:57
  • There is no actual reason to limit your writes to a size somewhat less than a guess at the MTU, and no way to actually control the TCP segment size in the first place. – user207421 Jul 10 '15 at 12:57
0

Melli has great reasoning in their answer about why you'd choose larger or smaller packets. You're basically trading throughput for responsiveness.

I don't agree that there isn't a correct answer; at least in this case I think there's very obviously a better answer: If you want it to arrive at the other end as fast as possible, send it all at once!

  • Less system calls to send the data
  • Less overhead because you're sending less TCP packets & less redundant headers
  • Fragmentation is the responsibility of the lower levels of the network stack, not your application
  • The resulting code will be much more simple
nevelis
  • 736
  • 6
  • 17