blog.wlami.com

Virtuelles Zuhause von Wladislaw Mitzel

UDP-Pakete in Java 20 mal schneller verschicken

An vielen Stellen bekommt man zu hören UDP sei verbindungslos. Die üblichen Beispiele zum Verschicken von UDP-Paketen in Java sehen dementsprechend folgendermaßen aus:

1
2
3
4
5
6
DatagramSocket sock = new DatagramSocket();
for (int i = 0; i < 1000; i++) {
  byte[] content = new Long(System.currentTimeMillis()).toString().getBytes();
  DatagramPacket packet = new DatagramPacket(content, content.length, InetAddress.getLocalHost(), 1337);
  sock.send(packet);
}

Dieser Code funktioniert wunderbar und verschickt bei meinen Tests knapp 1000 UDP-Pakete/Sekunde, bzw. braucht 1000ms zum Ausführen. Doch wir haben hier noch Potential nach oben:

Obwohl UDP verbindungslos ist, ist in den meisten Programmiersprachen eine “connect”-Methode vorhanden. Diese baut keine wirkliche Verbindung mit dem Server auf, sondern stellt im Socket ein Default-Ziel ein. Das heißt, dass man bei den folgenden UDP-Datagrammen nur noch den Inhalt und die Länge festlegen muss. Eine modifizierte Version des obigen Beispiels sieht so aus:

1
2
3
4
5
6
7
DatagramSocket s = new DatagramSocket();
s.connect(InetAddress.getLocalHost(), 1337);
for (int i = 0; i < 10000; i++) {
  byte[] content = new Long(System.currentTimeMillis()).toString().getBytes();
  DatagramPacket packet = new DatagramPacket(content, content.length);
  s.send(packet);
}

In Zeile 2 findet unser neuer connect()-Aufruf statt. Diesem übergeben wir Ziel-Host und -Port. In den folgenden Datagramm-Definitionen (Zeile 5) müssen wir das Ziel nicht mehr angeben. Dieses Vorgehen beschleunigt das zweite Beispiel um den Faktor 20! Denn zum Ausführen des zweiten Beispiels werden nur noch etwa 50ms benötigt.

Doch vorsicht: UDP gewährleistet nicht, dass Pakete ankommen. Ist euer Sender schneller als der UDP-Empfänger landen die Pakete im Nirwana.

3 Kommentare

Von: wlami um 19:04:01 am 18.02.2012

Hi, soweit ich weiß kommt es zu diesem Problem, wenn der Sender das Paket nicht bis zum Empfänger bekommt. Zum Beispiel könnte eine Firewall das Paket abfangen und diese Exception auslösen.

Von: André um 07:43:31 am 10.02.2012

Moin,
netter Beitrag, danke dafür! will es gerade selbst ausprobieren, bekomme aber bei der 2. (modifizierten) Version eine Exception Exception in thread "main" java.net.PortUnreachableException: ICMP Port Unreachable at java.net.PlainDatagramSocketImpl.send(Native Method) at java.net.DatagramSocket.send(DatagramSocket.java:625) at main.UDPSocketConnect.t2(UDPSocketConnect.java:41) at main.UDPSocketConnect.main(UDPSocketConnect.java:17)
woran kann das liegen? cheers andre

Von: Gerrit um 14:16:14 am 13.08.2012

Sehr schöner Beitrag, informativ und anschaulich! Bei mir hat sich die Geschwindigkeit bei einer Verbindung zum Localhost allerdings "nur" verdoppelt, von ≈360 zu 180 Millisekunden. Bei einer Verbindung zu Google hat sie sich etwas mehr als versechsfacht (≈30-190ms). Auf jeden Fall eine gewaltige Verbesserung. Danke!

Kommentieren

Dieses Blog verwendet statische Kommentare. Kommentare werden also per Mail an mich geschickt und erscheinen anschließend im Blog. Eure E-Mail-Adresse wird nicht veröffentlicht.

Kommentar schreiben