# Netzwerkgeschwindigkeit messen



## data89 (8. Jul 2009)

Hallo,

also mein neues Projekt beschäftigt sich (wie 99 % meiner Projekte) mit Netzwerken (weil das einfach das Spannenste ist ;-)).
Ich möchte die reale Geschwindigkeit also Übertragunsrate messen. Bisher habe ich nur mit Socket, ServerSocket, UDP-Sockets gearbeitet und Klassen geschrieben, die das Arbeiten damit erleichtern. Ich bin auch in der Theorie mehr oder weniger drin.

Außerdem muss ja ein Server und ein Client vorhanden sein (an beiden "Enden" des Netzwerkkabels).

Die Frage aller Fragen: *Ist ein Geschwindigkeitsmessen mit Java überhaupt möglich (denn Java sitzt ja hinter der JVM)?*

Ich frage mich, *wie man die Geschwindigkeit einer Netzwerkverbindung misst*. Könnte man verschieden große Pakete schicken und die Übertragunszeit messen? 

Das ist die eine Sache, dann hat man (hoffentlich) die UDP und die TCP/IP-Verbindung gemessen. Kann man irgendwie Informationen über die Auslastung der Netzwerk-Interfaces erhalten?

Ich freue mich auf Eure Kommentare,
data89


----------



## tuxedo (8. Jul 2009)

Klar kannst du da Messungen betreiben. 

>> Könnte man verschieden große Pakete schicken und die Übertragunszeit messen? 

Ist wohl ein guter Ansatz. Interessant wird hierbei auch die verwendete RX und TX Buffergröße auf dem Socket, sowie die Paketgröße sein. 

Auch solltest du mal nach "Nagle Algorithmus" googeln und diesen mal für deine Tests abschalten. Denke du bekommst da recht interessante Werte.

>> Kann man irgendwie Informationen über die Auslastung der Netzwerk-Interfaces erhalten?

Mit nativem Java sicher nicht. Ist auch nicht weiter Interessant, da du das selbst "errechnen" kannst. Wenn du weißt dass du ne 100mbit Karte hast, dann weißt du auch wieviel theoretisch über die Leitung geht. Und das kannst du dann mit dem vergleichen was du gemessen hast. Dann hast du deine "Auslastungsinformation", zumindest näherungsweise.

>> Die Frage aller Fragen: Ist ein Geschwindigkeitsmessen mit Java überhaupt möglich (denn Java sitzt ja hinter der JVM)?

Naja. Du kannst so natürlich nur messen, was sich mit Java übertragen lässt. Das OS selbst handhabt das ganze vielleicht "etwas" anders. Aber im großen und ganzen steht Java was die Netzwerkperformance betrifft den direkten OS-Netzwerkoperationen in nichts nach.

- Alex


----------



## data89 (8. Jul 2009)

Wie funktionert eine Messung jetzt genau?
Der Server sendet ein Paket an den Client und der Client sendet das Paket wieder zurück. Dann wird die benötigte Zeit durch zwei Geteilt und auf die Paketgröße gerechnet. Schon hat man eine Aussage xy KBit/s oder so. Aber der Client verarbeitet ja das Paket. Das benötigt ja auch Zeit.

Wenn man eine solche Messung implementiert hat - schön und gut. Aber dafür gibt es ja auch andere Programme. *Wie kann ich mein Projekt "Netzwerktools" noch sinnvoll erweitern?*

data89


----------



## tuxedo (8. Jul 2009)

"Wer misst, misst Mist ..."

Kommt halt drauf an was du messen willst.

Du kannst den "Round Trip Durchsatz" messen (so wie von dir beschrieben), oder aber du sendet einfach "alles was geht" und auf der anderen Seite "empfängst du alles was geht". Dann kannst du 2 Messungen machen: Wie Schnell kann ich Daten raussenden, und auf der anderen Seite: Wie schnell kann ich Daten empfangen.

Ich denke wenn man sich auch nur ein klein wenig selbst den Kopf darüber zerbricht und bei Unklarheiten mal 5min an die frische Luft geht kommt man selbst zu einem brauchbaren Ansatz.

Denn woher sollen WIR wissen was du wie messen kannst/willst/sollst.

Es gibt AFAIK kein genormtes, allgemeingültiges und übergeordnetes Messverfahren das DIE Netzwerkgeschwindigkeit misst. Du musst definieren was du messen willst, und das misst du dann einfach. Wenn Komponenten in die Messung mit einfließen, die du nicht im Ergebnis haben möchtest dann musst du diese erst identifizieren und dir dann überlegen wie du deine Messung umstellen/ändern kannst, so dass diese Komponenten entweder gar nicht mehr einfluss nehmen, oder nur noch eine minimale Rolle spielen.

- Alex

P.S. Fettschrift bringt dich auch nicht weiter.


----------



## data89 (8. Jul 2009)

> Ist wohl ein guter Ansatz. Interessant wird hierbei auch die verwendete RX und TX Buffergröße auf dem Socket, sowie die Paketgröße sein.



Was ist damit gemeint? Außerdem: Wie misst man zuverlässig die Übertragungszeit eines Pakets zwischen zwei Sockets?


> Der Server sendet ein Paket an den Client und der Client sendet das Paket wieder zurück. Dann wird die benötigte Zeit durch zwei Geteilt und auf die Paket. Das benötigt ja auch Zeit.



Wie bekomme ich außerdem verschieden große Pakete hin - natürlich, indem ich soviel reinpacke, wie ich will. Aber es fällt ja nicht nur ins Gewicht, was ich reinpacke. Es gibt ja auch noch einen Header ...

P.S.: Dann will ich es mal mit kursiver Schrift versuchen ;-)


----------



## tuxedo (8. Jul 2009)

Mal ehrlich: Du stellst dich gerade an wie "das Kind im Dreck" ...

Buffergrößen kann man auf dem Socket-Objekt setzen. Hilfe hierzu gibts in der API Doc.

Du kannst System.currentTimeMillis(); benutzen und Endzeit minus Startzeit ergibt dann die Dauer.

Allerdings geht das nur innerhalb eines Systems. Hast du Client und Server über 2 Maschinen getrennt, so kannst du nur die RoundTrip-Zeit messen: Also hin senden und warten  bis alles komplett zurückgeschickt wurde. Denn Rechnerübergreifend ist das mit dem Zeitmessen so ne Sache: Die Rechneruhren gehen nicht alle gleich. Und schon gar nicht auf 10ms genau (Windows kanns generell nicht genauer).

>> Wie bekomme ich außerdem verschieden große Pakete hin - natürlich, indem ich soviel reinpacke, wie ich will.

Richtig "erraten".  Wenn du 1.000.000 bytes senden willst, wirst du dies i.d.R. in bestimmter Häppchengröße machen. Und die kannst du frei definieren wenn du "write()" auf dem Socket aufrufst und das ganze für alle 1.000.000 bytes in eine while() schleife packst.

>> Aber es fällt ja nicht nur ins Gewicht, was ich reinpacke. Es gibt ja auch noch einen Header ...

Den Header kannst du nicht vbeeinflussen. Java kann nunmal nur TCP/IP. Wenn es "weniger" Overhead sein soll musst du auf UDP ausweichen.

Aber das kommt halt wieder drauf an was du messen willst: TCP oder UDP Geschwindigkeit. Wie groß der TCP/IP bzw. UDP Header auf dem Ethernet-Frame ist, verrät dir das internet.

- Alex


----------



## data89 (8. Jul 2009)

Ich hab mal folgendes gemacht:


> Ich denke wenn man sich auch nur ein klein wenig selbst den Kopf darüber zerbricht und bei Unklarheiten mal 5min an die frische Luft geht kommt man selbst zu einem brauchbaren Ansatz.



Es gibt ja "ping xy". Also habe ich (unter WinXP) mal einen ping an Google gestartet:

```
ping www.google.de

Ping www.l.google.com [74.125.39.106] mit 32 Bytes Daten:

Antwort von 74.125.39.106: Bytes=32 Zeit=59ms TTL=248
Antwort von 74.125.39.106: Bytes=32 Zeit=62ms TTL=248
Antwort von 74.125.39.106: Bytes=32 Zeit=62ms TTL=248
Antwort von 74.125.39.106: Bytes=32 Zeit=62ms TTL=248

Ping-Statistik für 74.125.39.106:
    Pakete: Gesendet = 4, Empfangen = 4, Verloren = 0 (0% Verlust),
Ca. Zeitangaben in Millisek.:
    Minimum = 59ms, Maximum = 62ms, Mittelwert = 61ms
```
D.h. Ein 32-Byte Paket benötigt ca. 61 ms, um einmal zu Server unter 74.125.39.106 hinzugelangen und zurück. Daraus folgt, dass eine Strecke ca. 30,5 ms benötig - was 0,0305 s sind. 32 Byte entsprechen ca. 0,3725 KB. Wenn ich nun z.B. KBit/s berechnen will, dann rechne ich 0,03125 kB/0,0305s = 1,0246 KBit/s.

Ist das vom Ansatz her richtig? Das Ergebniss kommt mir irgendwie komisch vor ...


----------



## tuxedo (8. Jul 2009)

Ping-Nachrichten sind ICMP Nachrichten und sind somit nicht direkt mit den TCP und UDP Packages die man mit Java senden kann vergleichbar.

Nebenbei hat Ping auch nicht das Ziel eine Transfergeschwindigkeit zu ermitteln. Ping misst viel eher die RoundTripTime die eine ICMP Nachricht HIN und wieder ZURÜCK braucht.

Google ist dein Freund


----------



## data89 (8. Jul 2009)

Aber müsste es nicht so gehen?

Gibt es denn nirgendwo eine Anleitung bzw. wohl eher eine theoretische Abhandlung für soetwas?


----------



## tuxedo (8. Jul 2009)

Du stellst dich an.. SOll ich dir vllt. n och den exakten Code liefern????

Deine "Technik" zum errechnen ist korrekt. Aber deine Technik zum messen ist falsch.

Schreib nen Java Client und nen Java Server. Der Client schickt XXX Bytes zum Server, welcher diese erwiedern muss. Am Client misst du wielange das braucht. Aus dem Wissen wieviel bytes du geschickt hast und wieviel Zeit vergangen ist kannst du die Geschwindigkeit ermitteln.

Je nachdem welche Buffergröße du benutzt hast, welche Paketgröße du benutzt, ob der Nagle-Algo aktiv ist oder nicht, ob du UDP oder TCP benutzt oder nicht, je nachdem wird das Ergebnis ausfallen.

- Alex


----------



## data89 (8. Jul 2009)

Danke für Deine Geduld mit mir


----------

