Datagram Socket & Datagram Channel performance

Hi,

I have been writing a video streaming server, and i have found that it does not perform anywhere near how it should (with available disk and network bandwidth). I have split the program down, and discovered that sending UDP packets appears to be running really slowly. Here is an example of the code i am using (sending blank packets for speed).

<code>

while (totalBytesSent < 150000000)

{

totalBytesSent += (188 * 7);

udpPacket.setData(payload);

udpPacket.setAddress(InetAddress.getByName("239.2.1.10"));

udpPacket.setPort(23232);

udpSocket.send(udpPacket);

}

</code>

it sends 150 megs of data in about 30 seconds = 5 meg/sec which is no where near the available bandwidth (gigabit lan).

So, i thought maybe the NIO packages are the solution, but i get similar performance using the datagram channel and byte buffers with this code:

<code>

while (totalBytesSent < 160000000)

{

inStream.read(fileBuf);

buffer.put(fileBuf);

buffer.flip();

bytesSent += udpChannel.send(buffer, destAddress);

buffer.position(0);

totalBytesSent += (188*7);

}

</code>

what am i doing wrong? is there a better way of sending data over a network? what I am essentially doing is trying to read directly from a file on the disk and send it straight over the network as fast as possible. Any help much appreciated.

Cheers

Robert Clarkson

[1513 byte] By [lanksa] at [2007-10-2 22:02:11]
# 1
Increase the sending socket's send buffer and the receiving socket's receive buffer, to somewhere around 63k.
ejpa at 2007-7-14 1:18:39 > top of Java-index,Core,Core APIs...
# 2
Thanks for your idea, I tried changing the setSendBufferSize(int size) to 63000 as you suggested. Unfortunately it made no difference.Do you have any other ideas?Cheers
lanksa at 2007-7-14 1:18:39 > top of Java-index,Core,Core APIs...
# 3
In case (1) you're constructing a new InetAddress per packet, which may involve DNS lookups, so I'd get rid of that.In case (2) you're copying data from one buffer to another, which is not necessary. Try reading and writing with the same buffer.
ejpa at 2007-7-14 1:18:39 > top of Java-index,Core,Core APIs...
# 4

Hi there, good ideas. I tried both of those and some new code. Nothing worked! I'm at the end of my tether here. What on earth could the problem be. Here is the new code i tried. It couldnt be simpler!

<code>

FileChannel rdr = (new FileInputStream("C:/media/amino.ts")).getChannel();

while (rdr.read(buffer) > 0)

{

buffer.flip();

bytesSent += udpChannel.send(buffer, destAddress);

buffer.clear();

}

</code>

lanksa at 2007-7-14 1:18:39 > top of Java-index,Core,Core APIs...
# 5

I don't know where your performance is going now, but you're in danger of not even sending all the data with this code.

The canonical form of the NIO copying loop is:

<code>

while (rdr.read(buffer) > 0 || buffer.position() > 0)

{

buffer.flip();

bytesSent += udpChannel.send(buffer,destAddress);

buffer.compact();

}

</code>

Your version assumes the write was complete; this doesn't. The write can return zero for example, in which case the data will just be lost in your version. Maybe that's where your throughput is going?

or OTOH does the computer you're running this on have more than 1 NIC? and if so is one slower than the other? You can see where I'm going with this.

ejpa at 2007-7-14 1:18:39 > top of Java-index,Core,Core APIs...