Belegten Port in Windows nach Programmabsturz wieder freigeben



  • Wenn ich mit einem Programm einen Port im Zugriff habe, auf dem das Programm Anfragen entgegen nimmt (indem ich zum Beispiel in einem .NET-Programm mit der Microsoft.Web.Services3-Bibliothek die Klasse EndpointReference und die Funktion SoapReceivers.Add benutze) und das Programm stürzt ab und kann daher das Freigeben des Ports nicht mehr realisieren, wie kann ich dann in Windows den Port wieder freigeben, damit andere Programme ihn wieder in Zugriff nehmen können?

    Ich habe die Erfahrung gemacht, dass der Port nach dem Absturz des Programms erst mal nicht benutzt werden kann. Wenn ich zum Beispiel das Programm erneut starte und es sich denselben Port nehmen will, geht es nicht, weil der Port noch als im Zugriff gilt.
    Nach einer gewissen Weile geht es wieder.
    Wie kann ich jetzt Windows dazu bringen, diesen Port direkt sofort wieder freizugeben?

    Im Moment habe ich das Problem in Windows Server 2003, aber falls es in jedem Windows anders gehandhabt werden muss, wäre es auch gut, wenn ich wüsste, wie das in anderen Versionen geht.



  • Kann man nicht für die Registrierungsanfrage (Aufforderung den Port zu reservieren, sofern möglich) eine Registrierungs-ID abrufen (get) oder ist die beim Rückgabewert (result) vielleicht schon dabei, wenn man eine Registrierungsanfrage macht?

    Mit der ID müsste man dann, die vergangene Registrierung kapern können, wenn Du z.B. in deinem Programm erst prüfen lässt ob der Port frei ist und wenn nicht, dann kapern. Wobei dann natürlich auch drin stehen müsste, dass wenn der Port frei ist, die Registrierungs-ID irgendwo abgelegt wird, damit dann, wenn das Programm neu gestartet wird (eine neue Instanz), die ID holen kann, denn mit dem Absturz gehen ja die Variablen verloren. Also die ID z.B. in eine Datei schreiben lassen.



  • mit setsockopt auf reuse setzen vor dem open usw.



  • @US_Army
    Hast du auch nur annähernd irgend einen Plan worum es hier überhaupt geht?

    @Der Kuli
    Ich kann dir auf die Schnelle nur nen Artikel geben der beschreibt wieso es dieses Problem überhaupt gibt:
    http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html

    Was auch noch relativ einfach geht ist das Delay zu verkürzen, also die Zeit die der Socket im TIME_WAIT Status bleibt. Lässt sich in der Registry einstellen, der entsprechende Key lässt sich schnell ergoogeln.

    Wo ich dir keinen Tip geben kann ist wie du den Status ganz vermeidest. setsockopt würde ich nicht unbedingt verwenden wollen, das hat was ich mich erinnern kann einige Nebeneffekte -- wie z.B. dass ein anderes Programm dann gleichzeitig auf den selben Port bind() en kann, während das erste noch läuft!



  • Das Beste wäre wohl dafür zu sorgen, dass das Programm nicht mehr abstürzt - oder zumindest noch ein wenig aufräumt 🙂



  • @geeky
    Das Programm kann aufräumen so viel es will, hilft nix.

    Wenn der Server eine Verbindungen von sich aus schliessen muss, weil er nicht darauf warten kann dass der Client ein FIN schickt, dann geht der Socket des Servers in den TIME_WAIT Status.

    Der Versuch bei einer Exception wegen der man den Server "crashen" lassen möchte noch schnell alle Connections zuzumachen ist also für die Katz, weil man dann genau so in TIME_WAIT landet, wie wenn das OS beim Wegräumen des Prozesses den Socket zumacht. Für den TCP/IP Stack macht es keinen Unterschied ob das "active close" vom OS oder von der Applikation selbst ausgelöst wird.



  • Richtig, ich habs nun durchgestrichen 😉



  • hustbaer schrieb:

    @US_Army
    Hast du auch nur annähernd irgend einen Plan worum es hier überhaupt geht?

    Mehr als das. Danke für die Nachfrage! Ich habe schon sehr oft gesehen wie welche das "try" benutzten, dabei bieten die meisten Objecte eine Variable/Eigenschaft zum ausfahren/beenden an. Zumal lässt sich ja ganz oft mit "if" ein fehlgeschlagener Start behandeln.



  • @US_Army
    Statt dummen Gebrabbel das mit der Sache genau gar nichts zu tun hat hättest du auch einfach gleich "nein" schreiben können.



  • hustbaer schrieb:

    @US_Army
    Statt dummen Gebrabbel das mit der Sache genau gar nichts zu tun hat hättest du auch einfach gleich "nein" schreiben können.

    Lass gefälligst das was ich schreibe meine Sache sein und mit deinem "gebrabbel" finde ich dich äußerst peinlich. Du kannst wahrscheinlich nicht mal eine Hintergrundprozessschleife anhalten.



  • ...



  • US_Army schrieb:

    hustbaer schrieb:

    @US_Army
    Statt dummen Gebrabbel das mit der Sache genau gar nichts zu tun hat hättest du auch einfach gleich "nein" schreiben können.

    Lass gefälligst das was ich schreibe meine Sache sein

    Gerne.
    Sobald du aufhörst zu versuchen irgendwo mitzureden und auf wichtig zu machen wo du keinen Plan von hast.

    Nur weil deine 13-jährige Schwester dir ein bisschen was übers Programmieren erzählt hat, heisst das nicht dass du dich auskennst.



  • hustbaer schrieb:

    US_Army schrieb:

    hustbaer schrieb:

    @US_Army
    Statt dummen Gebrabbel das mit der Sache genau gar nichts zu tun hat hättest du auch einfach gleich "nein" schreiben können.

    Lass gefälligst das was ich schreibe meine Sache sein

    Gerne.
    Sobald du aufhörst zu versuchen irgendwo mitzureden und auf wichtig zu machen wo du keinen Plan von hast.

    Nur weil deine 13-jährige Schwester dir ein bisschen was übers Programmieren erzählt hat, heisst das nicht dass du dich auskennst.

    Willst Du noch mehr Rätselraten über mich und dich blamieren oder wieder trollen?! Einen bootfähigen MBR kannst du wahrscheinlich auch nicht schreiben und an der richtigen Stelle platzieren.



  • US_Army schrieb:

    Kann man nicht für die Registrierungsanfrage (Aufforderung den Port zu reservieren, sofern möglich) eine Registrierungs-ID abrufen (get) oder ist die beim Rückgabewert (result) vielleicht schon dabei, wenn man eine Registrierungsanfrage macht?

    Mit der ID müsste man dann, die vergangene Registrierung kapern können, wenn Du z.B. in deinem Programm erst prüfen lässt ob der Port frei ist und wenn nicht, dann kapern. Wobei dann natürlich auch drin stehen müsste, dass wenn der Port frei ist, die Registrierungs-ID irgendwo abgelegt wird, damit dann, wenn das Programm neu gestartet wird (eine neue Instanz), die ID holen kann, denn mit dem Absturz gehen ja die Variablen verloren. Also die ID z.B. in eine Datei schreiben lassen.

    Hi, danke für deine Antwort. Wie du erkennen kannst an meiner Frage bin ich leider noch noob was sowas angeht. Kannst du mir das bitte genauer erklären oder einen kurzen Beispielcode posten? Welche API muss ich aufrufen damit das so klappt wie du sagst und woher kriege ich die Registrierungs-ID? Danke! ⚠ 🙂



  • Der Kuli schrieb:

    US_Army schrieb:

    Kann man nicht für die Registrierungsanfrage (Aufforderung den Port zu reservieren, sofern möglich) eine Registrierungs-ID abrufen (get) oder ist die beim Rückgabewert (result) vielleicht schon dabei, wenn man eine Registrierungsanfrage macht?

    Mit der ID müsste man dann, die vergangene Registrierung kapern können, wenn Du z.B. in deinem Programm erst prüfen lässt ob der Port frei ist und wenn nicht, dann kapern. Wobei dann natürlich auch drin stehen müsste, dass wenn der Port frei ist, die Registrierungs-ID irgendwo abgelegt wird, damit dann, wenn das Programm neu gestartet wird (eine neue Instanz), die ID holen kann, denn mit dem Absturz gehen ja die Variablen verloren. Also die ID z.B. in eine Datei schreiben lassen.

    Hi, danke für deine Antwort. Wie du erkennen kannst an meiner Frage bin ich leider noch noob was sowas angeht. Kannst du mir das bitte genauer erklären oder einen kurzen Beispielcode posten? Welche API muss ich aufrufen damit das so klappt wie du sagst und woher kriege ich die Registrierungs-ID? Danke! ⚠ 🙂

    Sei mir nicht böse aber das wird dich nicht viel weiter bringen und ich kann dir hier auch nicht die ganzen Artikel zu IP/TCP/UDP vorlesen. Also besser sich die Artikel selber durchlesen und lernen.

    Außerdem welche .NET-Sprache verwendest Du?

    Dein Programm stürzt ab, weil Du dabei bist was zu entwickeln?
    Lese Dir mal die ganzen Ereignisse die es in .NET geben kann durch. Es gibt da bestimmt ein Ereignis, was auch noch bei einem harten abbrechen, was man z.B. über die Entwickler-ID befehlen kann, erst abgearbeitet wird, bevor das Programm endgültig gekillt wird und da lässt Du die IP-Verbindung einfach schließen.

    Allerdings ist auch das "try" in der Entwicklungsphase geeignet. Lese Dir mal durch was "try" bedeutet. Ist ähnlich wie ein "if". Heißt man kann dann angeben was im Fall passieren soll, wenn der Versuch nicht geklappt hat. Da könnte man dann z.B. auch die IP-Verbindung schließen lassen.

    Wegen der Sache mit der Registrierungs-ID, ich weiß nicht ob .NET da was anbietet. Früher hat man ohne .NET Programme für Windows geschrieben (WinAPI) und damit auch mehr Kontrolle gehabt. Aber das ist hier eh in der falschen Kategorie. Vielleicht fragst Du das auch besser im .NET-Forum.



  • US_Army schrieb:

    Der Kuli schrieb:

    US_Army schrieb:

    Kann man nicht für die Registrierungsanfrage (Aufforderung den Port zu reservieren, sofern möglich) eine Registrierungs-ID abrufen (get) oder ist die beim Rückgabewert (result) vielleicht schon dabei, wenn man eine Registrierungsanfrage macht?

    Mit der ID müsste man dann, die vergangene Registrierung kapern können, wenn Du z.B. in deinem Programm erst prüfen lässt ob der Port frei ist und wenn nicht, dann kapern. Wobei dann natürlich auch drin stehen müsste, dass wenn der Port frei ist, die Registrierungs-ID irgendwo abgelegt wird, damit dann, wenn das Programm neu gestartet wird (eine neue Instanz), die ID holen kann, denn mit dem Absturz gehen ja die Variablen verloren. Also die ID z.B. in eine Datei schreiben lassen.

    Hi, danke für deine Antwort. Wie du erkennen kannst an meiner Frage bin ich leider noch noob was sowas angeht. Kannst du mir das bitte genauer erklären oder einen kurzen Beispielcode posten? Welche API muss ich aufrufen damit das so klappt wie du sagst und woher kriege ich die Registrierungs-ID? Danke! ⚠ 🙂

    Lese Dir mal die ganzen Ereignisse die es in .NET geben kann durch. Es gibt da bestimmt ein Ereignis, was auch noch bei einem harten abbrechen, was man z.B. über die Entwickler-ID befehlen kann, erst abgearbeitet wird, bevor das Programm endgültig gekillt wird und da lässt Du die IP-Verbindung einfach schließen.

    Allerdings ist auch das "try" in der Entwicklungsphase geeignet. Lese Dir mal durch was "try" bedeutet. Ist ähnlich wie ein "if". Heißt man kann dann angeben was im Fall passieren soll, wenn der Versuch nicht geklappt hat. Da könnte man dann z.B. auch die IP-Verbindung schließen lassen.

    Wegen der Sache mit der Registrierungs-ID, ich weiß nicht ob .NET da was anbietet. Früher hat man ohne .NET Programme für Windows geschrieben (WinAPI) und damit auch mehr Kontrolle gehabt. Aber das ist hier eh in der falschen Kategorie. Vielleicht fragst Du das auch besser im .NET-Forum.

    Achso, sorry, habe mich geirrt, du hast also leider doch keine Ahnung wovon du redest ("versuchs mal mit try", bwahaha) 😞

    Mit SO_REUSEADDR klappt's allerdings wie geschmiert 👍 , danke an alle (außer US Army).



  • Der Kuli schrieb:

    US_Army schrieb:

    Der Kuli schrieb:

    US_Army schrieb:

    Kann man nicht für die Registrierungsanfrage (Aufforderung den Port zu reservieren, sofern möglich) eine Registrierungs-ID abrufen (get) oder ist die beim Rückgabewert (result) vielleicht schon dabei, wenn man eine Registrierungsanfrage macht?

    Mit der ID müsste man dann, die vergangene Registrierung kapern können, wenn Du z.B. in deinem Programm erst prüfen lässt ob der Port frei ist und wenn nicht, dann kapern. Wobei dann natürlich auch drin stehen müsste, dass wenn der Port frei ist, die Registrierungs-ID irgendwo abgelegt wird, damit dann, wenn das Programm neu gestartet wird (eine neue Instanz), die ID holen kann, denn mit dem Absturz gehen ja die Variablen verloren. Also die ID z.B. in eine Datei schreiben lassen.

    Hi, danke für deine Antwort. Wie du erkennen kannst an meiner Frage bin ich leider noch noob was sowas angeht. Kannst du mir das bitte genauer erklären oder einen kurzen Beispielcode posten? Welche API muss ich aufrufen damit das so klappt wie du sagst und woher kriege ich die Registrierungs-ID? Danke! ⚠ 🙂

    Lese Dir mal die ganzen Ereignisse die es in .NET geben kann durch. Es gibt da bestimmt ein Ereignis, was auch noch bei einem harten abbrechen, was man z.B. über die Entwickler-ID befehlen kann, erst abgearbeitet wird, bevor das Programm endgültig gekillt wird und da lässt Du die IP-Verbindung einfach schließen.

    Allerdings ist auch das "try" in der Entwicklungsphase geeignet. Lese Dir mal durch was "try" bedeutet. Ist ähnlich wie ein "if". Heißt man kann dann angeben was im Fall passieren soll, wenn der Versuch nicht geklappt hat. Da könnte man dann z.B. auch die IP-Verbindung schließen lassen.

    Wegen der Sache mit der Registrierungs-ID, ich weiß nicht ob .NET da was anbietet. Früher hat man ohne .NET Programme für Windows geschrieben (WinAPI) und damit auch mehr Kontrolle gehabt. Aber das ist hier eh in der falschen Kategorie. Vielleicht fragst Du das auch besser im .NET-Forum.

    Achso, sorry, habe mich geirrt, du hast also leider doch keine Ahnung wovon du redest ("versuchs mal mit try", bwahaha) 😞

    Mit SO_REUSEADDR klappt's allerdings wie geschmiert 👍 , danke an alle (außer US Army).

    Na also! Hast Du gut gemacht! Besser es selber können!

    Nun solltest Du noch lernen, über andere nichts falsches zu erzählen und nichts im Mund herum zudrehen 🙂



  • schade das es TGGCs Netzkultur nicht mehr gibt, sonst würde er jetzt bestimmt zum Depp der Woche gewählt werden



  • bat´ schrieb:

    schade das es TGGCs Netzkultur nicht mehr gibt, sonst würde er jetzt bestimmt zum Depp der Woche gewählt werden

    Ich hab vergessen, was Du angestellt hast.



  • ...


Log in to reply