![]() |
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:
Ich habe herausgefunden dass es an einer "testconsole.exe" liegt die bereits läuft.
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.
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 |
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: |
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 |
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? |
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 |
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 |
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; |
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; |
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; |
Re: Could Not Bind Socket
Zitat:
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 01:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz