Ölü fakat dinleyen bir süreci nasıl öldürürüm?


48

Bağlantı noktasını 3000 dinleyen bir uygulama geliştiriyorum. Görünüşe göre hala bağlantı noktasını dinleyen bir örnek var çünkü başlattığımda bir dinleyici oluşturamıyor (C #, TcpListener, ama bu alakasız) çünkü bağlantı noktası zaten alınmış.

Şimdi, uygulama Görev Yöneticisi'nde mevcut değil, bu yüzden PID'sini bulmaya ve onu öldürmeye çalıştım, bu ilginç sonuca ulaştı:

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.

Bu davranışı daha önce görmedim ve birinin bir çözümü olup olmadığını görmek için yeterince ilginç olduğunu düşündüm.

GÜNCELLEME: Process Explorer'ı başlattım ve 3000'i aradım ve şunu buldum:

<Non-existent Process>(3000): 5552

Sağ tıkladım ve "Close Handle" ı seçtim. Artık İşlem Gezgini'nde değil, yine de netstat'ta görünüyor ve uygulamanın dinleyiciyi başlatmasını engelliyor.

GÜNCELLEME 2: İşlemi olarak gösteren Windows için TCPView bulundu "<non-existent>". CurrPorts gibi, bu araçtaki bağlantıyı kapatmaya çalıştığımda hiçbir şey olmuyor.


biraz hastayı öldürerek hastalığı tedavi edebilir, ancak bilgisayarı yeniden başlatırsanız durur mu?
Xantec

2
Aslında, çıkış yaptıktan ve tekrar tekrar yeterliydi, ama ... daha iyi bir çözüm bulmak için ben istiyorum hala gibi ben şimdi onu yeniden üretmek için başardınız
Srekel

Burada listelenen programlardan herhangi birinin yardım edip etmediğini kontrol edin
Sathyajith Bhat

1
Geçerli TCPView 3.05 sürümüyle <non-exsitent> işleminin bağlam menüsünden "Bağlantıyı kapat" benim durumumda bağlantıyı başarıyla kapattı ve bağlantı noktasını serbest bıraktı.
Ventzy Kunev

Yanıtlar:


13

Soketteki sonsuz beklemeleri önlemek için, programınız setsockopt işlevini SO_REUSEADDR ve SO_RCVTIMEO parametreleriyle kullanmalıdır:

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. 

1
Bu, belirli bir sorunu olan herkese yardımcı oldu mu?
rustyx

12

Aynı sorunu yaşadık ve artık mevcut olmayan işlem kimliğini aramak için Microsoft Sysinternals’tan İşlem Gezgini'ni kullandık .

Sürece birkaç DrWatson işlemi tarafından başvurulduğu ortaya çıktı. Bu işlemleri öldürmek limanı serbest bıraktı. DrWatson, Microsoft'a bellek dökümü göndermek için kullanılır ve bu, birkaç saat sürüyordu;


7

Bence CurrPorts’a bir şans vermelisin.

CurrPorts, yerel bilgisayarınızda halen açık olan tüm TCP / IP ve UDP bağlantı noktalarının listesini görüntüleyen ağ izleme yazılımıdır. Listedeki her bir bağlantı noktası için, bağlantı noktası açan işlemle ilgili bilgiler, işlem adı, işlemin tam yolu, işlemin sürüm bilgileri (ürün adı, dosya açıklaması vb.) Ve bu süre süreç ve onu yaratan kullanıcı yaratıldı.

Buna ek olarak, CurrPorts istenmeyen TCP bağlantılarını kapatmanıza, portları açan işlemi sonlandırmanıza ve TCP / UDP portları bilgilerini HTML dosyasına, XML dosyasına veya sekmeyle ayrılmış metin dosyasına kaydetmenize olanak sağlar.

CurrPorts ayrıca tanımlanamayan uygulamalara ait pembe renkle ilgili şüpheli TCP / UDP bağlantı noktalarını otomatik olarak işaretler (sürüm bilgisi ve simgeler içermeyen uygulamalar)

alt metin


4
Listede "Sistem" işlem adı altında gösterilir. Bağlantı noktasını kapatmaya zorlamak için öğeye sağ tıklamayı denedim, ancak hiçbir şey olmuyor.
Srekel

7

Muhtemel sorun, işleminizin soket tutamacını miras alan başka bir (çocuk) işlemi başlatmasıdır ve hala çalışıyordur.

Bunu önlemenin çeşitli yolları vardır, örneğin: ProcessStartInfo.NetShellExecute = true;


1
Teşekkürler, bu iyi bir şeydi. subprocess.call(..., cwd=..., shell=True)Bir python web sunucusunda bir uygulama başlatıcısı olarak çağırıyordum ve soketi serbest bırakmak için tüm bu alt işlemleri öldürmek zorunda kaldım. İşin garibi, ben kabuk = True kullanıyorum. Bu beni yıllarca rahatsız etti.
Daniel F,

Bir kabuk kullanmanın bu davranışa neden olduğunu sanmıyorum. Üst ölür, ben doğru yolu oluşturmaktır dendiğinde tüm alt işlemleri sonlandırmak isterseniz İş Nesnesi ile JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE bayrak , her çocuk sürecini eklemek AssignProcessToJobObject ve yakın doğal olarak zaman üst süreç çıkışları için kolu bırakın.
qris

1

Process Explorer'da işlemi görebiliyor musunuz? Eğer evetse, onu oradan öldürebilirseniz, ancak gerçekte ne olduğunu araştırdıktan sonra (işleme dahil yüklenen bütün işleri görebilirsiniz)


1

Netstat komutunuza '-b' bayrağı atmayı deneyin. Size portu kullanan çalıştırılabilir dosyanın adını söyleyecektir. Ardından görev yöneticisinde bu işlemi bulun ve orada öldürün. Bu işe yaramazsa, postayı açık tutan yürütülebilir dosya ne işe yaramazsa.


Şu anda onu çoğaltamıyorum, ancak işlemin adını bulmaya çalışırken yapılan diğer tüm girişimlerin (ve araçların) başarısız olduğundan, netstat'ın da yapamayacağından eminim.
Srekel

1

Burada oyalanmak teriminden bahsetmek gerekir .

Ayrıntılar http://msdn.microsoft.com/en-us/library/ms739165.aspx adresinde bulunabilir.

Kısaca: Soket sistemine, verilmemiş veriler varsa, kapatıldıktan sonra bile bir soketi açık tutmasını söyleyen bir seçenek vardır.

C # uygulamanızda Socket.SetSocketOption ile ilgili herhangi bir seçenek belirleyebilirsiniz: http://msdn.microsoft.com/en-us/library/1011kecd.aspx

Bahsedilen her şey gönderme ve müşterilerle ilgili olduğundan, ancak işimizdeki benzer sorunlarımız olduğundan, bazı ileri araştırmalar, buradaki örnekte gösterildiği gibi dinleyiciler için oyalan seçeneğini belirleyebileceğini ileri sürüyor: http://msdn.microsoft.com /library/system.net.sockets.tcplistener.server.aspx

Bazı çalışanlar, uygulama sonlandırıldıktan / yaklaşık iki dakika süreyle kapatıldıktan sonra OS tarafından limanların tutulduğundan bahsetti. Bu göz önüne alındığında, limanın belirli bir süre sonra tutulduğunu duymak ilginç olurdu.


Limanlar bundan daha uzun süre açık kaldı (ne kadar sürdüğümü ama belki bir saat kadar vazgeçip yeniden başlatmayı hatırlamıyorum).
Srekel

Oyalan seçeneğinin bu özel durumla alakalı olup olmadığından emin değilim, görünüşe göre, yalnızca CloseSocket çağrısından sonra ne olması gerektiğini belirtir. Uygulamayı öldürdüğümden beri, bu işlevin çağrıldığından şüpheliyim (?).
Srekel

1

Ben de bu sorunla karşılaşıyorum. Sonunda nedenimi buldum. Bunun sebebi c / c ++ 'da popen tarafından bir alt süreci başlatmasıdır. Ancak ana işlem çökmeden / kapanmadan önce pclose. Ardından liman, ana sürecin hala devam etmesini ve dinlemesini sağlar.


1
Bu cevabı ServerFault sitesinde faydalı buldum: serverfault.com/a/273727/8856
Harriv

1

Xdebug ile aynı problemi yaşadım, 9000 numaralı limanı açık bıraktı.

"Taskkill / pid xxxx" kullanarak cmd ile kapatmayı başardım.

Bağlantı noktasını kullanan işlemin pid'i "netstat -o" ile alınabilir.

Yapılandırmam 7 ev primi kazandı.


1

Aynı sorunu yaşadım ve düzelttim:

  • ile PID bulma netstat -o
  • Xp işlemi ile öldür

Netstat'ın bazen bir pid verebileceğini ancak ilgili çalıştırılabilir adı veremeyeceğini not etmek ilginçtir!


1

Ölü işlem bir veya daha fazla alt işlem başlattıysa sorun ortaya çıkabilir. Eğer

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
);

Bir çocuk sürecini başlatmak için kullanılmışsa, miras alma işleminin değerine bağlıdır.

bInheritHandles = false 

Ana işlem durdurulursa ve istemci işlemi hala çalışıyorsa, Windows bağlantı noktasını engellemez.


1

Kök neden, portların kalıtsal olarak yaratılan bir alt süreç olduğunda, üst süreç çökerken, alt süreç hala portu tutarken de benzer bir sorun olduğunu gördüm. Çözüm, hala çalışan çocuk sürecini belirlemek ve durdurmaktı. Buradaki örnekte var olmayan süreç PID 7336 idi

> wmic process get processid,parentprocessid | findstr/i 7336
7336             23828

Bu işlemi durdurmak için:

> taskkill /f /pid 23828

Ve bu sorunu çözdü.


0

Bir güvenlik duvarı kurduğunuzu sanmıyorum (veya herhangi bir Windows ağ tweeksini denediniz mi)?

Bazı güvenlik duvarları bu tür davranış sergilerler ve portları açık tutabilirler.

Bir tane varsa, devre dışı bırakmayı ve sonra programınızı başlatıp kapatmayı ve ne olduğunu görmeyi deneyin.


Maalesef bir seçenek değil, çünkü bilgisayarımdaki güvenlik duvarını kontrol edemiyorum.
Srekel

@Srekel - Hangi güvenlik duvarı? Sorunlarınız olduğu için, kişisel olarak sorunlara neden olduğunu düşünüyorum.
William Hilsum

0

İşleminiz Sistem olarak listelendiğinden, büyük olasılıkla bir "Sistem" komut isteminde onu öldürebilirsiniz. Sistem hesabının normal bir yöneticiden daha fazla ayrıcalığı vardır.

Cmd.exe için bir görev zamanlayarak "Sistem" cmd.exe'yi alabilirsiniz (zamanlayıcı Sistem olarak çalışır):

at 15:23 /interactive "cmd.exe" 

Bu zamanı yakın gelecekte bir şey için değiştirin. Makine konsolunda olduğunuzdan emin olun (normal terminal sunucusu oturumundaysanız, yeni cmd.exe dosyasını göremezsiniz. mstscKonsolda giriş yapın). Sanırım bunu yapmanın başka yolları var, ama bu geçmişte benim için işe yaradı.


0

Ben de aynı problem vardı. Süreç düştüğünde hata ayıklanıyordu ve hala askıda bir durumda kalan ve görüldüğü gibi debug işlemine atıfta bulunulan askıda bir durumda vsjitdebugger.exe işlemi vardı. Bu vsjitdebugger.exe işlemi öldürme sorunu çözdü.


0

TCPView ve Process Explorer'ın bir karma kullanımı benim için çalıştı;) İlk önce portu TCPView'da kullanan işlem kimliğine baktım. İşlem Gezgini'nde işlemi izole edin ve İşlem Gezgini'ni kullanarak işlemi sonlandırın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.