How to speed up Java DatagramSocket?

I am using the Java DatagramSocket class to send a UDP data graph to an endpoint. The datagram should arrive at the endpoint every 60 ms.

I find that DatagramSocket.Send can often take> 1 ms (close to 2) for packing and sending packets of no more than 56 bytes. This leads to the fact that my packets will be delivered with an interval of 62 ms, and not after 60 ms.

This is on a Windows Vista machine. This is how I measure time:

              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." );

Does anyone have any tips or tricks to speed up this process?

+3
source share
9 answers

You can use the Timer class to schedule an event.

    Timer timer = new Timer();
    TimerTask task = new TimerTask() {
        public void run() {
            //send packet here
        }};
    timer.scheduleAtFixedRate(task, 0, 60);

60 "run". 60 ( , / / .. ).

+6

, . UDP, IP Ethernet , , .

, , ( ), , CPU...

send 60 , , send(). 60 . , , (send() ) 60 , .

+4

, . , , , .

javadoc:

- (, ), , "". , ( , , Object.wait(long), ).

, , , , : DatagramPacket "" ...

    datagram.setData(out);
    socket.send(datagram);

gc, , .

+2

, " 59 ", . , , , . , , 60 .

, , UDP IP, , 56- , UDP IP, , . 8 UDP, 20 IP- . , .

, UDP, , , , . TCP , , . , , , . , . , 2 , .

+1

, . . , :

Java ScheduledThreadPoolExecutor, Java 5 JDK/JRE. ( , , Oracle JavaDoc)

ScheduledThreadPoolExecutor schedThPoolExec = new ScheduledThreadPoolExecutor(1);   

/*
 * 
 * cue a byte buffer for sending in equal segments on the udp port with a inter-pkt-delay
 * 
 */
public void send(byte[] data, String destinationHost, int destinationPort, double interPacketDelayMs) {

        long interDelayNanos = (long) ( interPacketDelayMs * 1000000.0 );

        schedThPoolExec.scheduleAtFixedRate( new SendPacketsTimerTask(data, destinationHost, destinationPort), 0, interDelayNanos , TimeUnit.NANOSECONDS);

}

/*
 * 
 *
 * 
 */

class SendPacketsTimerTask implements Runnable {

    int offset = 0;
    byte[] buffer;
    String host;
    int port;

    public SendPacketsTimerTask(byte[] buffer, String destinationHost, int destinationPort) {

        this.buffer = buffer;
        host = destinationHost;
        port = destinationPort;
    }

    @Override
    public void run() {

        if(offset + PKT_SIZE < buffer.length) {

            //copy from cue to packet               
            byte[] tmp_pkt_buffer = new byte[PKT_SIZE];
            System.arraycopy(buffer, offset, tmp_pkt_buffer, 0, PKT_SIZE);

            try {
                //send packet       
                socket.send( new DatagramPacket(tmp_pkt_buffer, tmp_pkt_buffer.length, InetAddress.getByName(host), port) );
                //increment offset
                offset += tmp_pkt_buffer.length;



            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } 

        }
    }
}

TimerTask ( ) . TimerTask, , , , .

, 15 + (). , 0,5 . , Thread.sleep ( nano-seconds true, - ). , 6 . Timer, , . , . , , . Timer , .

. ( ) Java " ", " " ) , WRONG. . Java 5 , , :)

+1

58 ?

, ( , NOC- ), , , , . , , .

, : , . .


Windows . , 1 . , , .

  public static void main(String... argv)
    throws InterruptedException
  {
    final int COUNT = 1000;
    long time = System.nanoTime();
    for (int i = 0; i < COUNT; ++i) {
      Thread.sleep(57);
    }
    time = System.nanoTime() - time;
    System.out.println("Average wait: " + (time / (COUNT * 1000000F)) + " ms");
  }

Windows XP 57,7 .

0

60 , 60 , . , , .

, 60 ? , , .

0

Java , , 60 . , "" , . , .

0

nanoTime, nano .

long diff = System.nanoTime() - nanoTime;  System.out.println(out.length + "" + diff + "ms." );

0

Source: https://habr.com/ru/post/1709128/


All Articles