Je développe une application qui écoute le port 3000. Apparemment, le port écoute toujours car, à chaque démarrage, il ne peut pas créer d'écouteur (C #, TcpListener, mais ce n'est pas pertinent) car le port est déjà pris.
L'application n'existe pas dans le gestionnaire de tâches. J'ai donc essayé de trouver son PID et de le tuer, ce qui a conduit à ce résultat intéressant:
C:\Users\username>netstat -o -n -a | findstr 0.0:3000
TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 3116
C:\Users\username>taskkill /F /PID 3116
ERROR: The process "3116" not found.
Je n'avais jamais vu ce comportement auparavant et pensais que c'était assez intéressant pour voir si quelqu'un avait une solution.
UPDATE: J'ai démarré Process Explorer et fait une recherche sur 3000 et constaté ceci:
<Non-existent Process>(3000): 5552
J'ai fait un clic droit dessus et choisi "Fermer le manche". Ce n'est plus dans Process Explorer, mais apparaît toujours dans netstat et empêche toujours l'application de démarrer l'écouteur.
UPDATE 2: Trouvé TCPView pour Windows qui affiche le processus sous la forme "<non-existent>"
. Comme avec CurrPorts, rien ne se passe lorsque j'essaie de fermer la connexion dans cet outil.
Pour éviter des attentes interminables sur le socket, votre programme doit utiliser la fonction de setsockopt avec les paramètres SO_REUSEADDR et SO_RCVTIMEO:
SO_REUSEADDR : Allows the socket to be bound to an address that is already in use.
SO_RCVTIMEO : Sets the timeout, in milliseconds, for blocking receive calls.
Nous avions le même problème et utilisions Process Explorer de Microsoft Sysinternals pour rechercher l'ID de processus qui n'existait plus.
Il s'avère que le processus a été référencé par plusieurs processus DrWatson. Tuer ces processus a libéré le port. DrWatson est utilisé pour envoyer des vidages de mémoire à Microsoft, ce qui prenait plusieurs heures, car le processus à l'origine du plantage contenait plusieurs dizaines de Go de mémoire à la fois.
Le problème probable est que votre processus a démarré un autre processus (enfant) qui a hérité du descripteur de socket et qu'il est toujours en cours d'exécution.
Il existe différents moyens d'éviter ce problème, par exemple: ProcessStartInfo.UseShellExecute = true;
Je pense que vous devriez essayer CurrPorts
CurrPorts est un logiciel de surveillance réseau qui affiche la liste de tous les ports TCP/IP et UDP actuellement ouverts sur votre ordinateur local. Pour chaque port de la liste, des informations sur le processus qui a ouvert le port sont également affichées, y compris le nom du processus, le chemin complet du processus, les informations de version du processus (nom du produit, description du fichier, etc.), l'heure à laquelle le processus a été créé et l'utilisateur qui l'a créé.
De plus, CurrPorts vous permet de fermer les connexions non désirées TCP, de tuer le processus qui a ouvert les ports et d'enregistrer les informations sur les ports TCP/UDP dans des fichiers HTML, XML ou Fichier texte délimité par des tabulations.
CurrPorts marque également automatiquement en rose les ports TCP/UDP suspects appartenant à des applications non identifiées (Applications sans informations de version et icônes)
Il faut mentionner le terme persister ici.
Les détails peuvent être trouvés à http://msdn.Microsoft.com/en-us/library/ms739165.aspx
En bref: Une option indique au système de socket de garder un socket ouvert même après sa fermeture si des données non envoyées sont présentes.
Dans votre application C #, vous pouvez spécifier les options connexes via Socket.SetSocketOption: http://msdn.Microsoft.com/en-us/library/1011kecd.aspx
Puisque tout ce qui est mentionné concerne l'envoi et les clients, mais que nous avions des problèmes similaires au travail, certaines recherches ultérieures ont révélé qu'il était possible de spécifier l'option de linger pour les écouteurs, comme le montre l'exemple ci-dessous: http://msdn.Microsoft.com/library/system.net.sockets.tcplistener.server.aspx
Certains collègues ont parlé des ports détenus par le système d'exploitation après une fermeture/fermeture d'application pendant environ deux minutes. Cela étant, il serait intéressant de savoir si le port est toujours tenu après un certain temps.
J'ai eu le même problème et résolu par:
netstat -o
Il est intéressant de noter que netstat peut parfois renvoyer un pid mais pas le nom de l'exécutable correspondant!
Pouvez-vous voir le processus dans Process Explorer? Si oui que vous pouvez le tuer à partir de là, mais seulement après avoir enquêté sur ce que c'est réellement (vous pouvez voir toutes les dll chargées dans le processus)
Je rencontre aussi ce problème. Finalement j'ai trouvé ma raison. C'est causé par le processus principal appelé un processus enfant par popen dans c/c ++. Mais le processus principal se bloque/se ferme avant d'appeler pclose. Ensuite, le port traitera le processus principal toujours actif et l'écoutera toujours.
nous avons rencontré un problème similaire lorsque la cause première était la création d’un processus enfant héritant des ports, le processus parent était bloqué, alors que le processus enfant détenait toujours le port. La solution consistait à identifier le processus enfant toujours en cours d'exécution et à l'arrêter. Dans l'exemple ci-dessous, le PID de processus non existant était 7336
> wmic process get processid,parentprocessid | findstr/i 7336
7336 23828
Pour arrêter ce processus:
> taskkill /f /pid 23828
Et cela a résolu le problème.
J'ai eu le même problème avec xdebug, il a laissé le port 9000 ouvert.
J'ai réussi à fermer avec cmd en utilisant "taskkill/pid xxxx".
Le pid du processus utilisant le port peut être récupéré avec "netstat -o".
Ma configuration était win 7 home premium.
Essayez de lancer un drapeau '-b' sur votre commande netstat. Il vous dira le nom de l'exécutable qui utilise le port. Puis trouvez ce proc dans le gestionnaire de tâches et tuez-le là. Si cela ne fonctionne pas, affichez l'exécutable qui maintient le port ouvert.
Le problème peut être causé si le processus mort a démarré un ou plusieurs processus enfants. Si
BOOL WINAPI CreateProcess(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
a été utilisé pour démarrer un processus enfant, cela dépend de la valeur des handles hérités, donc avec
bInheritHandles = false
Windows ne bloquera pas le port si le processus parent est arrêté et que le processus client est toujours en cours d'exécution.
Je ne suppose pas que vous avez un pare-feu installé (ou essayé de tweeks réseau Windows)?
Certains pare-feu présentent ce type de comportement et peuvent maintenir les ports ouverts.
Si vous en avez un, essayez de le désactiver, puis lancez votre programme et fermez-le pour voir ce qui se passe.
J'ai eu le même problème. Le processus était en cours de débogage alors qu'il se bloquait et il y avait toujours un processus vsjitdebugger.exe en attente suspendu qui faisait apparemment référence au processus en cours de débogage. Tuer ce processus vsjitdebugger.exe a résolu le problème.
Étant donné que votre processus est répertorié en tant que système, vous pouvez probablement le supprimer à l'invite de commande "Système". Le compte système a plus de privilèges qu'un administrateur ordinaire.
Vous pouvez obtenir un cmd.exe "System" en planifiant une tâche pour cmd.exe (le planificateur s'exécute en tant que système):
at 15:23 /interactive "cmd.exe"
Changer ce moment pour quelque chose dans un proche avenir. Assurez-vous également que vous êtes sur la console de l'ordinateur (si vous êtes sur une session de serveur Terminal Server normale, vous ne verrez pas le nouveau cmd.exe. Créez une connexion mstsc
à la console). Je suppose qu'il existe d'autres moyens de le faire, mais cela a fonctionné pour moi dans le passé.
Une utilisation hybride de TCPView et de Process Explorer a fonctionné pour moi;) J'ai d'abord cherché l'identificateur de processus qui utilisait le port dans TCPView. Isolé le processus dans Process Explorer et tué le processus à l'aide de Process Explorer.