ฉันจะฆ่ากระบวนการที่ตายแล้ว แต่ฟังได้อย่างไร


48

ฉันกำลังพัฒนาแอพที่ฟังพอร์ต 3000 ดูเหมือนว่ายังมีอินสแตนซ์ที่กำลังฟังพอร์ตอยู่เพราะเมื่อใดก็ตามที่ฉันเริ่มมันไม่สามารถสร้างผู้ฟัง (C #, TcpListener แต่นั่นไม่เกี่ยวข้อง) เพราะพอร์ตนั้นมีอยู่แล้ว ยึด

ตอนนี้แอพไม่มีอยู่ในตัวจัดการงานดังนั้นฉันพยายามค้นหา PID และฆ่ามันซึ่งนำไปสู่ผลลัพธ์ที่น่าสนใจนี้:

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.

ฉันไม่เคยเห็นพฤติกรรมนี้มาก่อนและคิดว่ามันน่าสนใจพอที่จะดูว่าใครมีทางออก

UPDATE: ฉันเริ่มต้น Process Explorer และค้นหา 3000 และพบสิ่งนี้:

<Non-existent Process>(3000): 5552

ฉันคลิกขวาแล้วเลือก "ปิดที่จับ" มันไม่ได้อยู่ใน Process Explorer อีกต่อไป แต่ยังคงปรากฏใน netstat และยังหยุดแอปไม่ให้เริ่มฟัง

ปรับปรุง 2: พบTCPView สำหรับ Windowsซึ่งแสดงกระบวนการ"<non-existent>"ดังนี้ เช่นเดียวกับ CurrPorts ไม่มีอะไรเกิดขึ้นเมื่อฉันพยายามปิดการเชื่อมต่อในเครื่องมือนี้


การรักษาโรคเล็กน้อยโดยการฆ่าผู้ป่วย แต่มันจะหยุดถ้าคุณรีสตาร์ทคอมพิวเตอร์?
Xantec

2
อันที่จริงแล้วการออกจากระบบและกลับเข้ามาอีกครั้งก็เพียงพอแล้ว แต่ตอนนี้ฉันสามารถสร้างมันขึ้นมาใหม่ได้แล้วดังนั้นฉันก็ยังต้องการหาวิธีแก้ปัญหาที่ดีกว่า ...
Srekel

ตรวจสอบว่ารายการใด ๆ ของรายการที่นี่ ช่วยได้หรือไม่
Sathyajith Bhat

1
ด้วยเวอร์ชันปัจจุบันของ TCPView 3.05 "ปิดการเชื่อมต่อ" จากเมนูบริบทของกระบวนการ <non-exsitent> ปิดการเชื่อมต่อในกรณีของฉันสำเร็จและปลดพอร์ต
Ventzy Kunev

คำตอบ:


13

เพื่อหลีกเลี่ยงการรอซ็อกเก็ตอย่างไม่สิ้นสุดโปรแกรมของคุณควรใช้ฟังก์ชัน setsockoptกับพารามิเตอร์ SO_REUSEADDR และ 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. 

1
สิ่งนี้ช่วยทุกคนที่มีปัญหานี้ (ฟังซ็อกเก็ตโดยกระบวนการที่ตายแล้ว) หรือไม่?
rustyx

12

เรามีปัญหาเดียวกันและใช้Process Explorerจาก Microsoft Sysinternals เพื่อค้นหา ID กระบวนการที่ไม่มีอยู่อีกต่อไป

ปรากฎว่ากระบวนการได้รับการอ้างอิงโดยกระบวนการหลาย DrWatson ฆ่ากระบวนการเหล่านั้นปล่อยพอร์ต DrWatson ใช้ในการส่งหน่วยความจำทิ้งไปยัง Microsoft และใช้เวลาหลายชั่วโมงเพราะกระบวนการที่ล้มเหลวถือหน่วยความจำหลายสิบ GB ในเวลานั้น


7

ฉันคิดว่าคุณควรจะลองCurrPort

CurrPorts เป็นซอฟต์แวร์ตรวจสอบเครือข่ายที่แสดงรายการพอร์ต TCP / IP และ UDP ที่เปิดอยู่ในปัจจุบันบนคอมพิวเตอร์ของคุณ สำหรับแต่ละพอร์ตในรายการข้อมูลเกี่ยวกับกระบวนการที่เปิดพอร์ตจะปรากฏขึ้นรวมถึงชื่อกระบวนการเส้นทางแบบเต็มของกระบวนการข้อมูลรุ่นของกระบวนการ (ชื่อผลิตภัณฑ์คำอธิบายไฟล์และอื่น ๆ ) เวลาที่ กระบวนการถูกสร้างขึ้นและผู้ใช้ที่สร้างมันขึ้นมา

นอกจากนี้ CurrPorts ยังอนุญาตให้คุณปิดการเชื่อมต่อ TCP ที่ไม่ต้องการฆ่ากระบวนการที่เปิดพอร์ตและบันทึกข้อมูลพอร์ต TCP / UDP ไปยังไฟล์ HTML, ไฟล์ XML หรือไฟล์ข้อความที่คั่นด้วยแท็บ

CurrPort ยังทำเครื่องหมายอัตโนมัติด้วยพอร์ต TCP / UDP ที่น่าสงสัยสีชมพูโดยเป็นเจ้าของโดยแอปพลิเคชันที่ไม่ปรากฏหลักฐาน (แอปพลิเคชันที่ไม่มีข้อมูลรุ่นและไอคอน)

ข้อความแสดงแทน


4
มันจะปรากฏขึ้นในรายการภายใต้ชื่อกระบวนการ "ระบบ" ฉันพยายามคลิกขวาที่รายการเพื่อบังคับปิดพอร์ต แต่ไม่มีอะไรเกิดขึ้น
Srekel

7

ปัญหาที่น่าจะเกิดขึ้นคือกระบวนการของคุณเริ่มต้นกระบวนการ (ลูก) อีกกระบวนการซึ่งสืบทอดการจัดการซ็อกเก็ตและยังคงทำงานอยู่

มีหลายวิธีในการป้องกันสิ่งนี้ตัวอย่างเช่น: ProcessStartInfo.UseShellExecute = true


1
ขอบคุณนี่เป็นสิ่งที่ดี ฉันเรียกsubprocess.call(..., cwd=..., shell=True)แอปนี้เป็นตัวเปิดใช้งานแอพในเว็บเซิร์ฟเวอร์ของไพ ธ อนและมันกลับกลายเป็นว่าฉันต้องฆ่ากระบวนการลูกทั้งหมดเพื่อปลดซ็อกเก็ต สิ่งที่แปลกคือฉันใช้ shell = True เรื่องนี้ทำให้ฉันรำคาญมานานแล้ว
Daniel F

ฉันไม่คิดว่าการใช้เชลล์จะทำให้เกิดพฤติกรรมนี้ หากคุณต้องการที่จะยุติกระบวนการเด็กทั้งหมดเมื่อผู้ปกครองตายฉันคิดว่าวิธีที่ถูกต้องคือการสร้างJob Objectด้วยการตั้งค่าสถานะ JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSEเพิ่มกระบวนการเด็กด้วยAssignProcessToJobObjectตามธรรมชาติ
qris

1

คุณเห็นกระบวนการในProcess Explorerหรือไม่ ถ้าใช่มากกว่าที่คุณสามารถฆ่ามันจากที่นั่น แต่หลังจากคุณตรวจสอบสิ่งที่มันเป็นจริง (คุณสามารถดู dll ทั้งหมดที่โหลดเข้าสู่กระบวนการ)


1

ลองขว้างธง '-b' บนคำสั่ง netstat ของคุณ มันจะบอกคุณชื่อของปฏิบัติการที่ใช้พอร์ต จากนั้นหา proc ใน task manager และฆ่ามันที่นั่น หากไม่ได้โพสต์สิ่งที่ปฏิบัติการคือการที่ถือพอร์ตเปิด


ฉันไม่สามารถทำซ้ำได้ในขณะนี้ แต่ฉันค่อนข้างมั่นใจว่าเนื่องจากความพยายามทุกครั้ง (และเครื่องมือ) ในการพยายามค้นหาชื่อของกระบวนการล้มเหลว netstat จะไม่สามารถทำได้เช่นกัน
Srekel

1

จำเป็นต้องพูดถึงอิทธิพลที่นี่

สามารถดูรายละเอียดได้ที่http://msdn.microsoft.com/en-us/library/ms739165.aspx

กล่าวโดยย่อ: มีตัวเลือกที่บอกให้ระบบซ็อกเก็ตเปิดซ็อกเก็ตไว้แม้ว่าจะถูกปิดหากมีข้อมูลที่ไม่ได้ส่ง

ในแอป C # ของคุณคุณสามารถระบุตัวเลือกที่เกี่ยวข้องผ่าน Socket.SetSocketOption: http://msdn.microsoft.com/en-us/library/1011kecd.aspx

เนื่องจากทุกสิ่งที่กล่าวถึงเกี่ยวข้องกับการส่งและลูกค้า แต่เรามีปัญหาในที่ทำงานคล้ายกันบางการค้นหาเพิ่มเติม reveled ว่าเราสามารถระบุตัวเลือกอิทธิพลสำหรับผู้ฟังดังแสดงในตัวอย่างที่นี่: http://msdn.microsoft.com /library/system.net.sockets.tcplistener.server.aspx

เพื่อนร่วมงานบางคนพูดคุยเกี่ยวกับพอร์ตที่จัดขึ้นโดยระบบปฏิบัติการหลังจากการปิด / ปิดแอปพลิเคชันประมาณสองนาที ระบุว่ามันน่าสนใจที่จะได้ยินว่าพอร์ตนั้นยังคงอยู่หลังจากผ่านไประยะหนึ่ง


พอร์ตถูกเปิดค้างไว้นานกว่านั้น (จำไม่ได้ว่านานแค่ไหน แต่อาจนานถึงหนึ่งชั่วโมงก่อนที่ฉันจะเลิกและรีบูต)
Srekel

ฉันไม่แน่ใจว่าตัวเลือกอิทธิพลเกี่ยวข้องกับกรณีนี้หรือไม่เนื่องจากดูเหมือนว่าจะระบุเฉพาะสิ่งที่ควรจะเกิดขึ้นหลังจากการโทรไปยัง CloseSocket เท่านั้น เนื่องจากฉันฆ่าแอปพลิเคชันฉันสงสัยว่าฟังก์ชั่นจะถูกเรียกใช้ (?)
Srekel

1

ฉันยังพบปัญหานี้ ในที่สุดฉันก็พบเหตุผลของฉัน มันเกิดจากกระบวนการหลักเรียกกระบวนการเด็กโดย popen ใน c / c ++ แต่กระบวนการหลักขัดข้อง / ปิดก่อนที่จะเรียกใช้ pclose จากนั้นพอร์ตจะจัดการกับกระบวนการหลักที่ยังคงอยู่และยังคงฟังอยู่


1
ฉันพบคำตอบนี้ที่ ServerFault มีประโยชน์: serverfault.com/a/273727/8856
Harriv

1

ฉันมีปัญหาเดียวกันกับ xdebug มันเปิดพอร์ตทิ้งไว้ 9000

ฉันจัดการเพื่อปิดด้วย cmd โดยใช้ "taskkill / pid xxxx"

pid ของกระบวนการที่ใช้พอร์ตสามารถดึงข้อมูลได้ด้วย "netstat -o"

การกำหนดค่าของฉันคือชนะ 7 พรีเมี่ยมที่บ้าน


1

ฉันมีปัญหาเดียวกันและแก้ไขได้โดย:

  • ค้นหา PID ด้วย netstat -o
  • ฆ่ามันด้วยโพรเซส xp

น่าสนใจที่จะทราบว่าบางครั้ง netstat สามารถส่งคืน pid ได้ แต่ไม่ใช่ชื่อที่สามารถเรียกทำงานได้ที่สอดคล้องกัน!


1

ปัญหาอาจเกิดขึ้นหากกระบวนการที่ไม่ทำงานได้เริ่มกระบวนการลูกอย่างน้อยหนึ่งกระบวนการ ถ้า

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

ถูกนำมาใช้เพื่อเริ่มกระบวนการเด็กมันขึ้นอยู่กับมูลค่าของการจัดการสืบทอดดังนั้นด้วย

bInheritHandles = false 

Windows จะไม่บล็อกพอร์ตหากกระบวนการหลักหยุดและกระบวนการไคลเอ็นต์ยังคงทำงานอยู่


1

เห็นปัญหาที่คล้ายกันเมื่อสาเหตุหลักคือกระบวนการลูกบางอย่างที่สร้างการสืบทอดพอร์ตกระบวนการหลักล้มเหลวขณะที่กระบวนการลูกยังคงถือพอร์ต การแก้ไขคือการระบุกระบวนการลูกที่ยังทำงานอยู่และหยุดมัน ในตัวอย่างที่นี่ PID กระบวนการที่ไม่มีอยู่คือ 7336

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

หากต้องการหยุดกระบวนการนี้:

> taskkill /f /pid 23828

และสิ่งนี้สามารถแก้ไขปัญหาได้


0

ฉันไม่คิดว่าคุณได้ติดตั้งไฟร์วอลล์ (หรือลองใช้เครือข่าย Windows ใด ๆ สองครั้ง)?

ไฟร์วอลล์บางตัวมีพฤติกรรมเช่นนี้และสามารถเปิดพอร์ตได้

หากคุณมีหนึ่งลองปิดการใช้งานและจากนั้นเปิดตัวโปรแกรมของคุณและปิดมันและดูว่าเกิดอะไรขึ้น


ไม่ใช่ตัวเลือกที่น่าเสียดายจริงๆเพราะฉันไม่สามารถควบคุมไฟร์วอลล์บนคอมพิวเตอร์ของฉันได้
Srekel

@Srekel - ไฟร์วอลล์มันคืออะไร? ในขณะที่คุณกำลังมีปัญหาฉันคิดว่าเป็นการส่วนตัวที่ทำให้เกิดปัญหา
William Hilsum

0

เนื่องจากกระบวนการของคุณอยู่ในรายการเป็นระบบส่วนใหญ่คุณสามารถฆ่ามันได้ในพรอมต์คำสั่ง "ระบบ" บัญชีระบบมีสิทธิ์มากกว่าผู้ดูแลระบบปกติ

คุณสามารถรับ "ระบบ" cmd.exe โดยกำหนดเวลางานสำหรับ cmd.exe (ตัวจัดตารางเวลาทำงานเป็นระบบ):

at 15:23 /interactive "cmd.exe" 

เปลี่ยนเวลาสำหรับบางสิ่งบางอย่างในอนาคตอันใกล้ ตรวจสอบให้แน่ใจว่าคุณอยู่ในคอนโซลของเครื่อง (ถ้าคุณอยู่ในเซสชันเทอร์มินัลเซิร์ฟเวอร์ปกติคุณจะไม่เห็น cmd.exe ใหม่ทำการmstscล็อกอินเข้าสู่คอนโซล) ฉันคิดว่ามีวิธีอื่นที่จะทำเช่นนั้น แต่สิ่งนี้ได้ผลสำหรับฉันในอดีต


0

ฉันมีปัญหาเดียวกันนี้ กระบวนการนี้กำลังถูกดีบั๊กขณะที่มันล้มเหลวและยังคงมีกระบวนการ vsjitdebugger.exe ในสถานะที่ถูกระงับซึ่งรออยู่ซึ่งดูเหมือนจะอ้างถึงกระบวนการที่กำลังดีบั๊ก การฆ่ากระบวนการ vsjitdebugger.exe แก้ไขปัญหาได้


0

การใช้ไฮบริดของ TCPView และ Process Explorer นั้นเหมาะกับฉัน;) ก่อนอื่นฉันดู id กระบวนการที่ใช้พอร์ตใน TCPView แยกกระบวนการใน Process Explorer และฆ่ากระบวนการโดยใช้ Process Explorer

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.