Portscanner

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Portscanner

Beitrag von Zudomon »

Huhu!

In meinem Programm soll es möglich sein, einen Port zu wählen. Bzw. wird dieser dann solange inkrementiert, bis ein freier Port gefunden ist.
Nun könnte man also dieses Programm mehrmals auf dem eigenen Rechner laufen haben... wie bekomme ich raus, an welchen Ports das Programm sitzt?
Spontan fällt mir da ebend nur ein, an jeden Port eine Nachricht zu schicken. Gibt es da keine elegantere Lösung? Kann man Ports auch direkt broadcasten lassen, so wie man es auch mit IP-Adressen im LAN machen kann?

Viele Grüße
Zudo
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: Portscanner

Beitrag von Sternmull »

Wie oft wird das Programm denn in tatsächlich gestartet? Das Hochzählen erscheint mir durchaus brauchbar wenn es nur um ein paar wenige gleichzeitig laufende Instanzen geht die sich einen Port in einem kleinen festgelegten Intervall nehmen sollen. Wenn mich nicht alles täuscht landet man aber mit bind() an Port 0 automatisch an einem der freien Ports. Das dürfte dann die beste Möglichkeit sein an einen freien Port zu gelangen.
Kann man Ports auch direkt broadcasten lassen, so wie man es auch mit IP-Adressen im LAN machen kann?
Man muss ja zwangsweise von einem Port aus Broadcasten. D.h. es wird von einem Port aus eine Nachricht an eine Broadcast-Adresse geschickt, und die kann dann an allen Ports empfangen werden. Dein Programm könnte also beim Start per Broadcast fragen welche Instanzen schon laufen. Diese müssten dann entsprechend antworten. Das neu gestartete Programm könnte sich daraufhin einen freien Port aussuchen. Wenn dir aber vollkommen egal ist an welchem Port sich die neue Instanz bindet, dann dürfte die automatische Zuweisung auf einen freien Port die bessere Wahl sein.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

Sternmull hat geschrieben:Wie oft wird das Programm denn in tatsächlich gestartet? Das Hochzählen erscheint mir durchaus brauchbar wenn es nur um ein paar wenige gleichzeitig laufende Instanzen geht die sich einen Port in einem kleinen festgelegten Intervall nehmen sollen. Wenn mich nicht alles täuscht landet man aber mit bind() an Port 0 automatisch an einem der freien Ports. Das dürfte dann die beste Möglichkeit sein an einen freien Port zu gelangen.
Kann man Ports auch direkt broadcasten lassen, so wie man es auch mit IP-Adressen im LAN machen kann?
Man muss ja zwangsweise von einem Port aus Broadcasten. D.h. es wird von einem Port aus eine Nachricht an eine Broadcast-Adresse geschickt, und die kann dann an allen Ports empfangen werden. Dein Programm könnte also beim Start per Broadcast fragen welche Instanzen schon laufen. Diese müssten dann entsprechend antworten. Das neu gestartete Programm könnte sich daraufhin einen freien Port aussuchen. Wenn dir aber vollkommen egal ist an welchem Port sich die neue Instanz bindet, dann dürfte die automatische Zuweisung auf einen freien Port die bessere Wahl sein.
Der Broadcast geht anscheinend nur an den ausgesuchten Port...
Das Problem ist auch, dass ich ja nicht einen freien Port suche, sondern den, hinter welchem sich das Programm verbirgt...

Ob es dann sinnvoll ist, wirklich einen festen Bereich für die Ports der Programme vorzugeben, der unveränderbar ist?
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: Portscanner

Beitrag von Sternmull »

Tatsache, um den broadcast zu empfangen muss man sich an den entsprechenden Port binden. Die gängige Lösung scheint die Festlegung auf einen bestimmten (aber konfigurierbaren) Port zu sein. So hab ich es zumindest bisher bei allen Netzwerkspielen gesehen. Im LAN ist man dann wohl darauf angewiesen das man den Port kennt auf dem laufende Server ihre Dienste Broadcasten. Also besser vorher mal Googeln um keinen Default-Port zu verwenden der von anderen benutzt wird, denn es kann sich ja immer nur ein socket an einen UDP-Port binden.

Für Server die ihre Dienste im Internet anbieten ist der Port aber kein Problem mehr. Dort werden laufende Spiele dann durch einen Master-Server publiziert der eine Liste aller aktiven Server verwaltet. Neu gestartete Server melden sich dort an (und teilen auch ihren Port mit, der kann dann also frei gewählt werden). Die Clients fragen den Masterserver nach der Liste und wissen dann wie sie die Server erreichen können.
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: Portscanner

Beitrag von Sternmull »

Hab grad entdeckt das man per SO_REUSEADDR festlegen kann das sich mehrere UDP-Sockets an den gleichen Port binden können. Damit dürfte das Problem eigentlich glöst sein: Wenn dein Programm das macht, dann stört es sich nicht daran falls andere auch diesen Port verwenden, es muss halt nur die Messages ignorieren die es nicht versteht (was es ja grundsätzlich machen sollte). Dann dürften nur andere Programme ein Problem haben wenn sie den gleichen Port verwenden wollen und kein SO_REUSEADDR verwenden, aber die haben dann halt Pech gehabt.

Edit: Allerdings darf nicht bereits ein Socket ohne SO_REUSEADDR an den Port gebunden sein. Ansosten geht auch ein bind() mit SO_REUSEADDR schief.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Portscanner

Beitrag von BeRsErKeR »

Bau dir doch einfach einen kleinen Port-Manager, der auch auf dem Rechner läuft. Der hat immer einen festen Port und alle deine Programm-Instanzen melden sich beim Start beim Port-Manager an und teilen ihm mit welchen Port sie nutzen. Dann kannst du von außen einfach beim Port-Manager anfragen und weißt welcher Port, welcher Instanz zugeordnet ist. Dafür muss dann natürlich immer der Port-Manager laufen. Aber das sollte ja kein Problem sein.
Ohne Input kein Output.
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: Portscanner

Beitrag von Sternmull »

BeRsErKeR hat geschrieben:Bau dir doch einfach einen kleinen Port-Manager, der auch auf dem Rechner läuft. Der hat immer einen festen Port und alle deine Programm-Instanzen melden sich beim Start beim Port-Manager an und teilen ihm mit welchen Port sie nutzen. Dann kannst du von außen einfach beim Port-Manager anfragen und weißt welcher Port, welcher Instanz zugeordnet ist. Dafür muss dann natürlich immer der Port-Manager laufen. Aber das sollte ja kein Problem sein.
Dafür gibt es keinen Grund. Statt einem zusätzlichen "Portmanager-Prozess" dessen Port bekannt sein muss, reicht es wenn das eigentliche Programm den richtigen Port kennt. Per Multicast kann jede Instanz Nachrichten an alle anderen Instanzen im LAN schicken und von ihnen empfangen. Das Problem einen freien Port zu finden bleibt so oder so.
Jaw
Beiträge: 54
Registriert: 14.07.2004, 01:00
Wohnort: Raum Düsseldorf

Re: Portscanner

Beitrag von Jaw »

Och ich find einen Manager durchaus eine mögliche Lösung. Ob es der beste Ansatz ist kann man nicht sagen, da man zu wenig über das Programm und seinen Zweck weiß. Aber unterm Strich fällt mir nix anderes ein. Entweder man hat einen bekannten Port, auf dem entweder das Prog selbst hört oder ein Informationsdienst der dann Auskunft gibt, oder man muss Bereiche scannen, wenn der Port unbekannt ist. So funktioniert eigentlich alles, was mir jetzt ad hoc einfällt. Lookups oder Broadcasts setzen immer auf irgendeiner bekannten Konstante auf, wie einen Port.

Mich würde mal interessieren, was diese Programme denn tun sollen, warum es mehrere Instanzen gibt, was sich da wie finden will und was da so ausgetauscht wird. Vielleicht können auch mehrere Threads oder Instanzen auf einem Port laufen und nur ihre Pakete verarbeiten, wenn man diese entsprechend mit ID versieht.

-Jaw
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

Jaw hat geschrieben:Mich würde mal interessieren, was diese Programme denn tun sollen, warum es mehrere Instanzen gibt, was sich da wie finden will und was da so ausgetauscht wird.
Das Programm soll anderen Spass und mir Geld bringen :D
Siehe http://zfx.info/viewtopic.php?f=10&t=1320

Ich habe es nun so gelöst, dass ich einfach nicht nur die IP sondern auch den Port zentral bekannt mache, wo dann der Client nachschauen kann. Habe noch ein paar Probleme, dass sich die Clients warum auch immer nicht wirklich finden, aber da werde ich noch ein wenig rumprobieren.
Einige haben mir schon beim testen beigestanden... :D

So wie es aussieht, kann ich mir sogar das Broadcasten im LAN dadurch sparen...

Achso, und das Programm soll halt so laufen, dass man direkt connected ist... ich mag es nicht, dass man sich erst anmelden muss oder so... lieber Programm öffnen und in der virtuellen Welt mit anderen sein...
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Portscanner

Beitrag von BeRsErKeR »

Da versteh ich nun aber nicht mehr wozu man mehrere Instanzen auf einem Rechner laufen lassen soll und wozu man verschiedene Ports braucht.
Ohne Input kein Output.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

BeRsErKeR hat geschrieben:Da versteh ich nun aber nicht mehr wozu man mehrere Instanzen auf einem Rechner laufen lassen soll und wozu man verschiedene Ports braucht.
Also die verschiedenen Ports brauch ich, damit man später einen Port frei wählen kann.
Und mehrere Instanzen auf einem Rechner, damit ich es bei mir testen kann, hab im moment nur einen Rechner hier stehn.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Portscanner

Beitrag von BeRsErKeR »

Zudomon hat geschrieben:Also die verschiedenen Ports brauch ich, damit man später einen Port frei wählen kann.
Und was soll das bringen?

Zudomon hat geschrieben:Und mehrere Instanzen auf einem Rechner, damit ich es bei mir testen kann, hab im moment nur einen Rechner hier stehn.
Naja aber deswegen mehrere Ports zu nutzen finde ich nicht wirklich sinnvoll.
Ohne Input kein Output.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

BeRsErKeR hat geschrieben:
Zudomon hat geschrieben:Also die verschiedenen Ports brauch ich, damit man später einen Port frei wählen kann.
Und was soll das bringen?
Ich dachte, wenn der Port fest ist und dann ein anderes Programm diesen schon belegt, wäre das nicht so gut... aber genau kenn ich mich nicht aus.
BeRsErKeR hat geschrieben:
Zudomon hat geschrieben:Und mehrere Instanzen auf einem Rechner, damit ich es bei mir testen kann, hab im moment nur einen Rechner hier stehn.
Naja aber deswegen mehrere Ports zu nutzen finde ich nicht wirklich sinnvoll.
Auch hier dachte ist, ein Programm sollte immer nur einen Port nutzen... und bei 2 Instanzen sollte dann auch jedes sein eigenen Port haben.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Portscanner

Beitrag von BeRsErKeR »

Es gibt bestimmte Port-Ranges, die fest vergeben sind (z.B. 80 für http usw). Man unterscheidet zwischen "Well Known Ports" (0-1023), "Registered Ports" (1024-49151) und "Dynamic/Private Ports" (49152-65535). In der Regel nutzt man also eine Portnummer aus letzterer Range. Diese kann zwar prinzipiell von jedem genutzt werden, aber verbreitete Dienste und Programme nutzen in der Regel registrierte Portnummern und sollten dir daher nicht in die Quere kommen. Es steht dir natürlich auch frei eigene Portnummern zu registrieren, aber soweit ich weiß muss dein Programm dafür eine gewisse Verbreitung und Bekanntheit erlangen. Man kann ohne Regstrierung nicht eindeutig einen Port einer Applikation zuordnen, aber dieses Los teilen so ziemlich alle Freeware-Projekte oder Computerspiele. Daher solltest du dir über sowas nicht all zu viele Gedanken machen und einfach einen festen Port aus dem Bereich 49152-65535 nutzen.

Mir fällt auch grad kein Grund ein, weshalb es nicht möglich sein soll, dass zwei oder mehr Programme auf einem Rechner den selben Port nutzen. Der Port ist doch nur Teil der Socket-Adresse. Du erstellt in jeder Programminstanz einen eigenen Socket, der halt die spezielle Adresse nutzt. Klar du kannst die Instanzen nicht direkt über den Port auseinander halten, aber das kann man ja einfach über eine Kennung lösen, die man austauscht.
Ohne Input kein Output.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

Ich muss doch mit "bind" meinen Socket an einen bestimmten Port binden, damit ich an diesem Daten empfangen kann... aber sobald eine Instanz gebunden ist, kann die andere nicht mehr auf dem Port lauschen...
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: Portscanner

Beitrag von Sternmull »

Ähm... hast du überhaupt gelesen was ich geschrieben hab? Dort hab ich nämlich beschrieben wie sich dieses Problem lösen lässt. Noch mal ganz deutlich: Siehe setsokopt und SO_REUSEADDR!
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

Sternmull hat geschrieben:Ähm... hast du überhaupt gelesen was ich geschrieben hab? Dort hab ich nämlich beschrieben wie sich dieses Problem lösen lässt. Noch mal ganz deutlich: Siehe setsokopt und SO_REUSEADDR!
Sorry, natürlich hatte ich deine Beiträge gelesen... aber irgendwie bin ich dann doch wieder durch andere Dinge so abgelengt worden, dass ich das schon wieder völlig aus meiner Realität verloren habe... werde mir das aber noch anschauen.
Danke, dass du dir nochmal die Mühe machst, mich darauf aufmerksam zu machen! War wirklich keine böse Absicht. ;)
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

@Sternmull
Es scheint mit deinem Tipp zu klappen, dass der bind Befehl dann in mehr als einer Instanz aufgerufen werden kann. Ohne das die Fehlermeldung kommt, dass schon ein Port belegt wäre.
Allerdings erhält nur die zuerst geöffnete Instanz sämtliche Pakete.
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: Portscanner

Beitrag von Sternmull »

Sendest du denn auch an die Broadcast-Adresse 255.255.255.255? Bei mir hat das funktioniert, hab mehrere Clients (horchen auf dem Port) und Server (Broadcasten auf dem Port) auf zwei Rechnern in einem LAN laufen lassen und alle Clients haben alle Pakete von allen Server gesehen, sowohl die von Instanzen auf dem gleichen System, als auch die von dem anderen.

Zum Testen hab ich mir ein Python-Skript ergoogelt und angepasst:

Code: Alles auswählen

#!/usr/bin/python2
# -*- coding: utf-8 -*-
import socket, time, sys

#UDP_IP="127.0.0.1"
UDP_IP="255.255.255.255"
UDP_PORT=6666

print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT

sock = socket.socket( socket.AF_INET, # Internet
                      socket.SOCK_DGRAM ) # UDP

# Broadcast erlauben
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)

# bind() für den Port festlegen das sich auch weitere Sockets 
# an diesen Port binden dürfen (müssen aber selber auch dieses
# Flag setzen).
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

#print sock.getsockname()

if len(sys.argv) != 2:
        print "Usage:"
        print "  udp.py cln     Listen for broadcast packages and print them"
        print "  udp.py srv     Broadcast packages with a timestamp"

if sys.argv[1] == 'srv':
        while True:
	print "broadcasting..."
		sock.sendto("broadcast at " + str(time.time()), (UDP_IP, UDP_PORT) )
		time.sleep(.5)
elif sys.argv[1] == 'cln':
	sock.bind(("0.0.0.0", UDP_PORT))
	while True:
		print "recieving..."
		msg = sock.recvfrom(10000)
		print "recieved:", msg
else:
        print "bad commandline"
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

Danke für deine Hilfe!
Da wollte ich gerade den Post schreiben, dass es bei mir trotzdem nichts bringt... also wenn man das Programm 3 mal aufmacht, dann sieht nur das erste Programm die anderen beiden... sobald man dann das erste Programm schließt, bekommt das zweit geöffnete aufeinmal die Daten des dritten.
Wie gesagt, dass wollte ich gerade so schreiben, als mir klar wurde, dass die aber dann untereinander doch einmal Kontakt hatten, weil sonst würden die anderen beiden Programme garnicht ihre Daten senden...
Ich habe da zwei Phasen... in der einen wird gebroadcastet, in der zweiten dann nur noch die Daten an die entsprechenden Kontakte geschickt... also habe jetzt mal versucht, immer zu broadcasten und dann klappt es auch, also muss ich irgendwo anders den Fehler gemacht haben. Werde da nun mal genauer schauen.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Portscanner

Beitrag von BeRsErKeR »

Ich weiß immer noch nicht ob es Sinn macht, sich lange mit dieser Thematik zu beschäftigen, nur damit man was testen kann. Frag doch einfach mal nen Kumpel, ob du seinen Rechner für Testzwecke nutzen kannst.

Falls du aber dennoch rumprobieren willst: Man kann soweit ich weiß sockets zwischen Prozessen austauschen bzw. sie an andere Prozesse übergeben. Unter Linux könnte das mit fork gehen, bei Windows kann das glaub ich das WSA-Gedöns (Stichwort: WSADuplicateSocket). Unter Unix kann man wohl auch mit AF_UNIX einen Shared Socket erstellen. Habe damit leider auch keine Erfahrung, aber man hat so einiges gehört/gelesen.
Ohne Input kein Output.
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

BeRsErKeR hat geschrieben:Ich weiß immer noch nicht ob es Sinn macht, sich lange mit dieser Thematik zu beschäftigen, nur damit man was testen kann. Frag doch einfach mal nen Kumpel, ob du seinen Rechner für Testzwecke nutzen kannst.
Es macht insofern Sinn, weil ich dann auf einem Rechner schnell und einfach schauen kann, ob der Multiplayer funktioniert. Vor allem ist mir wichtig, dass die Animationen dann auch möglichst Synchron ablaufen. Wenn man dann gegen einen Stein hackt und da diese kleinen Partikel rausfallen, dann wäre es geil, wenn auch diese übertragen würden... ich denke, für diese ganzen Kleinigkeiten ist es schon Sinnvoll, das auf einem Monitor nebeneinander zu sehen.
Also es klappt nun, wenn ich die Nachrichten auch als Broadcast schicke... erstmal lass ich es dann so. Wie du schon sagst, will ja jetzt kein halbes Jahr Zeit darein investieren, sondern möglichst schnell weiter kommen.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Portscanner

Beitrag von Chromanoid »

wie wäre es mit einem parameter für die exe? so mache ich das wenn ich solche einstellungen übergeben möchte...
Benutzeravatar
Zudomon
Establishment
Beiträge: 2257
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Portscanner

Beitrag von Zudomon »

@Chromanoid
Für was meinst du jetzt?
Also später sollte wohl nur überhaupt eine Instanz von dem Spiel laufen dürfen...
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4263
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Portscanner

Beitrag von Chromanoid »

Zudomon hat geschrieben:@Chromanoid
Für was meinst du jetzt?
Naja ein Teil deines Problems war doch, dass du deine Programme an einem PC testen willst. Ich hätte das ganze einfach über die Laufzeit-Konfiguration meiner IDE gemacht (oder eine Batch-Datei, je nach Unterstützung und so). Einfach pro Instanz selbst den Port und die zu bindende IP Adresse angeben ggf. mit Remote-Adresse für den Server. So vielleicht:
spiel.exe -bind 127.0.0.1:27001 -server
spiel.exe -bind 127.0.0.1:27002 -remote 127.0.0.1:27001
spiel.exe -bind 127.0.0.1:27003 -remote 127.0.0.1:27001
spiel.exe -bind 127.0.0.1:27004 -remote 127.0.0.1:27001
Antworten