# Netzwerk-IP´s sammeln



## B00n (21. Jan 2006)

Aloa Gemeinschaft,
wollt mal fragen, ob es mit Java möglich ist, die gesammten IP´s, die im gleichen Netzwerk sind, wie der User meines Progs, zu sammeln... vll irgendeine Methode schon von Java vorgegeben? 

*Das ping-Beispiel will ich nicht nehmen (gucken, ob die Ping-Abfrage beantwortet wird)*

THX B00n


----------



## Dukel (21. Jan 2006)

Wie willst du ohne Ping wissen ob ein Rechner an ist oder nicht?


----------



## stiewen (21. Jan 2006)

LOL eben genau das hab ich doch euch gefragt oder? :-D
hat Java keine Methode "getIPs" oder so???
Und mit Ping wollte ich nicht arbeiten, weil das zu lange dauert, erst alle IPs durchzugehen ...


----------



## Grizzly (21. Jan 2006)

stiewen hat gesagt.:
			
		

> LOL eben genau das hab ich doch euch gefragt oder? :-D
> hat Java keine Methode "getIPs" oder so???
> Und mit Ping wollte ich nicht arbeiten, weil das zu lange dauert, erst alle IPs durchzugehen ...


Du willst also keine Verbindung zu den Rechnern aufbauen und trotzdem ihre IPs wissen? Naja, eine Möglichkeit wäre am Netzwerk zu lauschen. Ab und zu kommt dann ein Paket vorbei, das zwar nicht für den eigenen Rechner ist, aber das ist ja egal. Und dort steht ja eine Absender IP drin. Die kann man sich dann merken.

Die Sache hat allerdings drei Schönheitsfehler:
1.) Mit Java hat man keine Möglichkeit auf so tiefe Funktionen zuzugreifen.
2.) Das Lauschen würde ewig brauchen. Und wenn ein Rechner zwar im Netz ist, aber toter Mann spielt, bekommst Du dessen IP auch nicht mit.
3.) Wenn Du irgendwelche Netzwerk-Hardware zwischen den Rechnern hast, die nicht jedes IP Paket in jeden Winkel des Netzwerkes schickt, dann bekommst Du von einigen Rechner auch nichts mit. Ich denke hier an Switches, Router & Co.


----------



## Illuvatar (21. Jan 2006)

So eine Methode gibt es in keiner Programmiersprache. Windows stellt so eine Fuktionalität bereit, wenn du mit Runtime#exec "net view" aufrufst, dann gibt dir Windows eine Liste mit allen Namen der Computer zurück, das müsstest du eben parsen, mit der Klasse InetAddress kommst du ja dann auch an die IPs.

Das sinnvollste ist so eine ping Methode afaik dennoch. Eine sehr gute Implementierung von so etwas hat einmal jemand hier geschrieben: http://www.java-forum.org/de/viewtopic.php?t=13625

Dies funktioniert aber nur um wirklich Server zu finden, die dasselbe Programm am laufen haben. Für alle IPs musst du dann doch ein richtiges ping machen - aber es empfiehlt sich natürlich, alle gleichzeitig zu pingen, und nicht nacheinander.


----------



## Grizzly (21. Jan 2006)

Illuvatar hat gesagt.:
			
		

> So eine Methode gibt es in keiner Programmiersprache.


Naja, wie gesagt: Wenn man sehr Lowlevel auf die Netzwerkkarte zugreift, könnte man den gesamten Netzwerkverkehr im eigenen Segment abhören.

Und _net view_ funktioniert nur in einem reinen Windows Netzwerk. Sobald Du andere IP Geräte drin hast, bekommst Du schon nicht mehr alle (bspw. Print Server).


----------



## Bßßn (21. Jan 2006)

Sag mal Grizzly, find ich ja toll, was du so alles weißt, aber hab ich irgendwo gesagt, dass ich im Net lauschen will? Ich habe lediglich gefragt, ob Java sowas bereitstellt... ein "nein" hätte auch gereicht!

So, ... 

Ich hab mal hier geschaut und mir das zum implementieren heruntergeladen: www.galileocomputing.de/openbook/javainsel2/java_160014.htm#Rxxjava_160014258Ping

jedoch ist dort ja auch eine dll datei... Wenn ich aber mein Prog an andere Leute weiter gebe, müssen die diese ja immer in den Windows ordner reinpacken oder? Oder muss ich da an eine install meines progs denken, die die dll installt?


----------



## Bleiglanz (21. Jan 2006)

Leichter wäre es, wenn ein Linux-Server in dem Netzwerk installiert ist

auf diesem den LISa ausführen (http://lisa-home.sourceforge.net/) und dann auf Port 7741 einfach die ergebnisse abholen (das ginge vom Client aus auch mit Java)


----------



## B00n (21. Jan 2006)

So, nachdem ich was für Java gefuden hab, (ICMP) hab ich aber nen Prob damit:


```
int inTemp = 0;
      String strparent = "";
      StringTokenizer stparent = new StringTokenizer(net.getHostAddress(), ".");
      while ( inTemp < 3 ) {
        if ( stparent.hasMoreElements() ) {
          strparent += stparent.nextToken() + ".";
        }
        inTemp++;
      }
      inTemp = 0;
      PingICMP ping = new PingICMP();
      ping.begin();
      while ( inTemp < 256 ) {
        if ( ping.ping(strparent + inTemp, 5, 1) ) {
          /* HashMap: Key = Number; Value = IP */
          frmain.hmIPs.put(inTemp + "", strparent + inTemp);
        }
        inTemp++;
      }
```

In der ersten schleife ermittle ich die IP bis zur Stelle, wo die eigene von allen Rechnern hinkommt...
In der zweiten schleife gehe ich alle IP durch und schaue, ob sie ansprechbar sind!

1. Kann mr einer sagen, für was die zahlen in der Methode PingICMP.ping(String, int, int) stehen? Was bewirken die???
2. beim Durchgehen der Schleife meint er, dass alle IP "anpingbar" sind! Wie kann das sein? Ich hab nur *.2 und *.4 im netzwerk hier...


----------



## Dante (21. Jan 2006)

jedes subnetz hat eine broadcast-adresse (x.x.x.255), wenn man die anpingt sollten alle rechner im subnetz antworten, klappt unter *nix zB. mit ping x.x.x.255 -b


----------



## stiewen (25. Jan 2006)

Hat den jemand noch eine andere Lösung, als die, die ich genannt habe oder wie muss ich meine Lösung noch verändern, dass sie funktioniert... 
Ich will nur die IP haben, die im Netzwerk vergeben sind ... 

THX


----------



## Murray (25. Jan 2006)

PingICMP ist ja keine Standard-Library, da kann man erstmal nur raten (oder googeln). Meinst Du estadisticas.icmp.PingICMP?

In diesem Fall kehrt ping schon zurück, wenn es gelungen ist, das Paket erfolgreich zu versenden; das ist noch keine Garantie dafür, dass auch auch eine Antwort kommt. Um auf eine Antwort zu warten, braucht man die pong-Methode, die aber blockiert, so dass man sie in einen getrennten Thread aufrufen muss, wenn das Programm nicht endlos warten soll.


----------



## AlArenal (25. Jan 2006)

Anmerkung:

Nicht jeder Rechner antwortet auf Ping....


```
ping [url]www.microsoft.de[/url]
```


----------



## Murray (25. Jan 2006)

Seit dem JDK 1.5 gibt es in java.net.InetAddress die Methode isReachable. Das würde dann etwa so funktionieren:

```
import java.net.InetAddress;

public class Test {

	public static void main( String[] args) {
		try {
		
			
			InetAddress a = InetAddress.getLocalHost();
			
			//--- letztes Byte von 1..254 variieren
			byte[] ba = a.getAddress();
			for (byte i=1; i<255; i++) {
				ba[3] = i;
				a = InetAddress.getByAddress( ba);
				System.out.println( a + ":" + (a.isReachable( 2000) ? "reachable" : "unreachable"));
			}
		} catch ( Exception e) {
			e.printStackTrace();
		}
	}
}
```

Natürlich funktioniert auch das nicht immer und überall; es bleibt grundsätzlich auch der VM überlassen, wie das implementiert wird. Lt. Doku kann man wohl davon ausgehen, dass das per ICMP-ECHO oder alternativ einer Socket-Verbindung zu Port 7 passiert.


----------



## Illuvatar (25. Jan 2006)

Nun ja, und wenn es da, sagen wir, 5 PCs im Netzwerk gibt, muss man nur noch 250 * 2 Sekunden auf die restlichen warten...


----------



## Murray (25. Jan 2006)

Mit dem Timeout muss man natürlich etwas experimentieren; je nach Netz kommt man vermutlich auch mit deutlich geringeren Werten klar.

Sollte man so etwas aber wirklich praktisch nutzen wollen, so würde man vermutlich mehrere Threads parallel arbeiten lassen; man könnte auch mit einem kurzen Timeout beginnen, die Adressen, die geantwortet haben, "abhaken" und die restlichen mit einem höheren Timeout erneut angehen usw.. 

Das sind aber Optimierungen, die man machen kann, wenn sich die Vorgehensweise als solche im fraglichen Netz als tauglich erweist; vorher hat das keinen Sinn (und würde wohl auch den Rahmen dieses Threads sprengen).


----------



## Murray (25. Jan 2006)

Ergänzung zum InetAddress-Beispiel: hier habe ich einen hübschen Anfängerfehler gemacht (schäm): die Schleife

```
for (byte i=1; i<255; i++) { 
  ba[3] = i;
```
terminiert nicht, da ein byte nie so groß werden kann (bei i<255 kommt ein impliziter Cast auf int ins Spiel).

Besser:

```
for (int i=1; i<255; i++) { 
  ba[3] =(byte) i;
```

//EDIT: Aussage korrigiert


----------

