Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Could Not Bind Socket (https://www.delphipraxis.net/138892-could-not-bind-socket.html)

aegidos 19. Aug 2009 12:20


Could Not Bind Socket
 
Hallo,
Ich nutze Delphi 2007 und habe gerade ein Problem mit einer UDP Komponente die in einem Teil meines Projektes verwendet wird.
Ich bin absoluter Newbie auf dem Gebiet Indy und UDP Sockets. Wenn ich mein Programm starte bekomme ich immer eine
Delphi-Quellcode:
Im Projekt myProgramm.exe ist eine Exception der Klasse EIdCouldNotBindSocket mit der Meldung 'Socket konnte nicht gebunden werden. Adresse und Port werden bereits benutzt.' aufgetreten.
Ich habe herausgefunden dass es an einer "testconsole.exe" liegt die bereits läuft.
Wie kann ich nun in der Initialisierung meines Programms suchen ob schon eine Prozess mit einem bestimmten Namen ("testconsole.exe") läuft?

Wenn ich die Prozess ID herausbekommen kann dann kann ich ja die "testconsole.exe" die den Socket blockiert abschiessen oder?
Die "testconsole.exe" welche den Socket blockiert ist auch von mir und wird durchs Programm myProgramm.exe gestartet, diese läuft noch weiter wenn das Programm unsachgemäß beendet wurde (Taskmanager oder so).

Wie finde ich die Stelle in meinem Projekt an der die UDPClient Connection etabliert wird? offensichtlich handelt es sich um eine Komponente die über den Objectinspektor irgendwo in eine Form reingezogen wurde. Kann man in Delphi2007 nach sowas suchen?

Ich bin sehr ratlos da ich nichteinmal das Window finde indem der PORT eingestellt ist bei der UDPSocket Komponente. Muss ich mir da über Ansicht ein bestimmtes Fenster anzeigen lassen?

Das waren jetzt sehr viele Fragen auf einmal ich hoffe mir kann jemand von euch weiterhelfen.

Schöne Grüße
Andi

wicht 19. Aug 2009 12:26

Re: Could Not Bind Socket
 
Ich denke, die Architektur deiner Applikation/Applikationen sollte überdacht werden. Warum müssen beide den gleichen Port verwenden? Warum muss das eine das andere starten und wieder beenden?
Das hört sich alles sehr komisch an... :stupid:

aegidos 19. Aug 2009 12:38

Re: Could Not Bind Socket
 
Die Architektur ist vom Anwender Vorgegeben. Der Anwender erzeugt exe Files (Consolenanwendungen) die über einen UDP Port ferngesteuert werden können und/oder Ein und Ausgaben über den UDP Port verschicken.

Meine Applikation liegt darüber und bildet die GUI zu den unterlagerten exe Files. Der Kunde hat schon hunderte solche KonsolenAnwendungen und möchte diese behalten jedoch eine schöne Benutzeroberfläche dazu haben.

Mein Programm etabliert also eine UDP Verbindung zur Konsolenapplikation und wertet deren output aus, dieser wird dann graphisch aufbereitet.

GUI <---> ConsolenApp

wird meine Applikation (GUI) aber dann durch einen Absturz oder den Taskmanager beendet läuft die ConsolenApp weiter und blockiert weiter den Port.

GUI X---> ConsolenApp

Jetzt kann meine GUI auch nicht mehr gestartet werden da die ConsolenApp schon läuft. Ich benötige also eine Funktion die mir die Prozess ID von z.B. ConsolenApp.EXE gibt und einer weitere Funktion mit der ich die ConsolenApp.Exe abschiessen kann.

Wenn ich ConsolenApp nämlich über den Taskmanager terminiere dann kann ich auch meine GUI wieder starten.

Aber danke für den Vorschlag. Würde ich das ganze neu Implementieren dann hätte ich auch eine ganz andere Architektur gewählt soviel steht fest!

Grüße
Andi

wicht 19. Aug 2009 12:52

Re: Could Not Bind Socket
 
Hm. Das ist ja ganz schön verrückt :-D . Wenn es das GUI-Teil aber nur einmal gibt und es sich nach Absturz nicht neustarten lässt, durch die Konsolenanwendungen, bedeutet das nicht, dass GUI und Konsolen-App beide als Server fungieren? Sollte das so sein, warum kann man dann die Konsolen-App nach der GUI starten?
Läuft das alles auf dem selben Rechner oder auf jedem Rechner im Netz einmal, also die Konsolenanwendungen?

aegidos 19. Aug 2009 13:09

Re: Could Not Bind Socket
 
Hy Wicht,

Die GUI ist der Server, an dem meldet sich die ConsolenApp dann an als Client und öffnet den gleichen Port zur Kommunikation mit der GUI.

Es läuft immer nur eine GUI und eine ConsolenApp zeitgleich auf einem Rechner.
Die ConsolenApp hat immer den gleichen Namen. Daher auch meine Idee mit dem TerminateProcess (hab ich aus der Delphi Hilfe).
Aber wie komm ich an das "hProcess: Cardinal" was der TerminateProcess als Übergabeparameter haben will?

Warum allerdings mein UDP-Server nicht mehr startet wenn noch ein UDP Client (ConsolenApp) auf dem Socket läuft weiss ich auch nicht genau.

Auf alle Fälle muss ich diese ConsolenApp irgendwie zum terminieren zwingen da sonst meine GUI nicht mehr startet. Die GUI kannst du dir auch als Monitoringtool vorstellen die überwacht welche ConsolenApp sich anmeldet am UDP-Server. Ich habe oben geschrieben es gibt nur immer eine ConsolenApp die gleichzeitig läuft aber vorher habe ich ja auch erwähnt dass es 100rte solcher EXEs gibt.
Die heissen immer gleich aber tun intern etwas anderes und schicken immer eine ID über den UDP Port zur GUI. Diese wird protokoliert.

Hast du ne Idee wie ich an ein "Processhandle" komme wenn ich den Namen der ConsolenApp habe ??

Danke !!!

Greetz
Andi

Klaus01 19. Aug 2009 13:13

Re: Could Not Bind Socket
 
..vielleicht habe ich die ganze Zeit ja UDP nicht richtig verstanden.
UDP ist ein verbindungsloses Protokol - es interessiert m.E. daher nicht ob auf der
Gegenstelle der Port existiert, in Benutzung ist oder nicht vorhanden ist.
Bei TCP wäre das schon eher ein Problem.

Grüße
Klaus

wicht 19. Aug 2009 13:44

Re: Could Not Bind Socket
 
Ungetestet und stumpf gepostet, teilweise von anderen Seiten zusammenkopiert und auf Fehlerbehandlung verzichtet:

Delphi-Quellcode:
function ToeteExeName(exeFileName: string): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeFileName))) then
    begin
      hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, FProcessEntry32.PID); //(kA ob es .PID heißt)
      TerminateProcess(hProcess);
      CloseHandle(hProcess);
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;

aegidos 19. Aug 2009 13:55

Re: Could Not Bind Socket
 
Danke wicht,
Es funktioniert !!
Hab den Code hier übernommen:
Delphi-Quellcode:
function TMainForm.GetProcess(Process: String; KillProcess: Boolean): Boolean;
var                
  hProcSnap     : THandle;
  pe32           : TProcessEntry32;

begin
Result := False;
hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
If hProcSnap <> INVALID_HANDLE_VALUE then
  begin
   pe32.dwSize := SizeOf(ProcessEntry32);
   If Process32First(hProcSnap, pe32) then
    While Process32Next(hProcSnap, pe32) do
     begin
      If Pos(Process, LowerCase(pe32.szExeFile)) <> 0 then
       begin
        If KillProcess then
         begin
           Result := TerminateProcess(OpenProcess(Process_Terminate, False, pe32.th32ProcessID), 0)
         end
        //If KillProcess then Result := TerminateProcess(OpenProcess(Process_Terminate, False, pe32.th32ProcessID), 0)
        Else Result := True;
        Break;
       end;
     end;
    CloseHandle(hProcSnap);
  end;
end;

wicht 19. Aug 2009 14:38

Re: Could Not Bind Socket
 
Mach es lieber so, sonst gibt's ein Handle-Leak (glaube ich):

Delphi-Quellcode:
var
  hProc: Cardinal
  // ...
begin
        // ...
        If KillProcess then
         begin
           hProc := OpenProcess(Process_Terminate, False, pe32.th32ProcessID);
           if hProc <> 0 then
           begin
             Result := TerminateProcess(hProc, 0)
             CloseHandle(hProc); // <<---
           end;
         end
         // ...
end;

xxl1 19. Aug 2009 15:03

Re: Could Not Bind Socket
 
Zitat:

Zitat von Klaus01
..vielleicht habe ich die ganze Zeit ja UDP nicht richtig verstanden.
UDP ist ein verbindungsloses Protokol - es interessiert m.E. daher nicht ob auf der
Gegenstelle der Port existiert, in Benutzung ist oder nicht vorhanden ist.
Bei TCP wäre das schon eher ein Problem.

Grüße
Klaus

naja aber der server muss ja trotzdem den socket registrieren, sprich binden

aegidos hast du mal den timeout abgewartet? wenn dein programm abschmiert bleibt der socket trotzdem noch vom system für ne gewisse zeit unregistrierbar...zumindest ist das bei tcp so


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:24 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz