Entwickler-Ecke

Internet / Netzwerk - Sockets: Ist ein Port noch frei?


Martok - Sa 06.10.12 19:51
Titel: Sockets: Ist ein Port noch frei?
Hi!

Ich brauche für eine API einen beliebigen freien TCP-Port, den ich dann dem Host-Programm zwecks Kommunikation übermittle.
Momentan fange ich einfach bei irgend einer Zahl an und zähle von dort aus durch, in der Hoffnung dass ich nicht so viele brauche dass ich einen anderen Server treffe.

Die Frage nach dem "Port belegt oder nicht" hatten wir schonmal [http://www.entwickler-ecke.de/viewtopic.php?t=82799], da war dann die Antwort "Socket aufmachen, wenn's eine Exception gibt ist da schon wer".

Ist das wirklich die einzige Möglichkeit, oder gibts dafür eine Abfrage-Funktion?
Irgendwie gefällt mir das nämlich nicht, mit etwas Pech wären das ja eine Reihe von Exceptions, und Debuggen in der IDE kann man dann vergessen.

Viele Grüße,
Martok


Gerd Kayser - Sa 06.10.12 20:26

Ich hab es zwar nicht getestet, aber gerade mehrfach im Internet gefunden:

Zitat:
With Indy just set the port to 0, and it will assign a free port for you.


Quelle u. a.: http://www.delphigroups.info/2/4f/188923.html

Vielleicht hilft es Dir weiter.


Narses - Sa 06.10.12 23:04

Moin!

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
Ich brauche für eine API einen beliebigen freien TCP-Port
Was für einen denn, einen listening-port für einen Server? Oder einen Client, dann kann man das der WSA überlassen, wie user profile iconGerd Kayser schon sagte.

Ansatz für einen Server-Port: mit netstat -a an der Kommandozeile kann man sich eine Portliste holen, also gibt´s da auch irgendeine API drunter, mit der man so eine Portliste kriegen kann. Notfalls das Tool nehmen und die Ausgabe auswerten. :nixweiss:

cu
Narses


Martok - Sa 06.10.12 23:19

Moin!

user profile iconGerd Kayser hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
With Indy just set the port to 0, and it will assign a free port for you.
Das...

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Was für einen denn, einen listening-port für einen Server? Oder einen Client, dann kann man das der WSA überlassen, wie user profile iconGerd Kayser schon sagte.
... funktioniert wunderbar ;)
Die Sache mit der 0 war genau das richtige Stichwort, stellt sich raus dass das allgemein immer mit bind() geht [http://msdn.microsoft.com/en-us/library/windows/desktop/ms737550(v=vs.85).aspx], unabhängig davon ob man danach connect oder listen macht.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  procedure SetupServer(var aServer: TServerSocket);
  var
    ia: sockaddr_in;
    sz: integer;
  begin
    aServer:= TServerSocket.Create(Self);
    aServer.OnClientRead:= OnServerData;

    aServer.Port:= 0;
    aServer.Active:= True;
    sz:= SizeOf(ia);
    getsockname(aServer.Socket.SocketHandle, ia, sz);
    aServer.Tag:= ntohs(ia.sin_port);
  end;


Damit bindet mir die WSA einfach den Socket an "irgendeinen" Port. Den lese ich dann zurück und leg ihn im Tag ab (in .Port geht nicht, da kann man nicht schreiben, während der Socket aktiv ist). Dann kann ich der API mitteilen dass sie bitte da ihre Daten abwerfen soll und alles funktioniert.

Damit ist das der zweite "ist der Port noch frei"-Thread, der dann ganz anders gelöst wurde. Klingt langsam nach einem Fall von falsche Frage.

Dannke,
Martok