Làm thế nào để tôi giết một quá trình đã chết nhưng lắng nghe?


48

Tôi đang phát triển một ứng dụng nghe trên cổng 3000. Rõ ràng có một trường hợp ứng dụng vẫn nghe cổng vì bất cứ khi nào tôi khởi động nó, nó không thể tạo ra một trình nghe (C #, TcpListener, nhưng điều đó không liên quan) vì cổng đã có sẵn Lấy.

Bây giờ, ứng dụng không tồn tại trong Trình quản lý tác vụ, vì vậy tôi đã cố gắng tìm ra PID của nó và giết nó, dẫn đến kết quả thú vị này:

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.

Tôi chưa từng thấy hành vi này trước đây và cho rằng nó đủ thú vị để xem có ai có giải pháp hay không.

CẬP NHẬT: Tôi đã khởi động Process Explorer và thực hiện tìm kiếm 3000 và tìm thấy điều này:

<Non-existent Process>(3000): 5552

Tôi nhấp chuột phải vào nó và chọn "Đóng Xử lý". Nó không còn trong Process Explorer, nhưng vẫn hiển thị trong netstat và vẫn ngăn ứng dụng khởi động trình nghe.

CẬP NHẬT 2: Đã tìm thấy TCPView cho Windows hiển thị quá trình dưới dạng "<non-existent>". Giống như với CurrPorts, không có gì xảy ra khi tôi cố gắng đóng kết nối trong công cụ này.


một chút chữa khỏi bệnh bằng cách giết chết bệnh nhân, nhưng nó có dừng lại nếu bạn khởi động lại máy tính không?
Xantec

2
Trên thực tế, đăng xuất và đăng nhập lại là đủ, nhưng giờ tôi đã có thể sao chép nó để tôi vẫn muốn tìm một giải pháp tốt hơn ...
Srekel

Kiểm tra nếu có trong những chương trình được liệt kê ở đây giúp đỡ
Sathyajith Bhat

1
Với phiên bản hiện tại của TCPView 3.05 "Đóng kết nối" từ menu ngữ cảnh của quy trình <non-exsitent> đã đóng thành công kết nối trong trường hợp của tôi và giải phóng cổng.
Ventzy Kunev

Câu trả lời:


13

Để tránh sự chờ đợi vô tận trên ổ cắm, chương trình của bạn nên sử dụng hàm setsockopt với các tham số SO_REUSEADDR và ​​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
Điều này có giúp được ai với vấn đề đặc biệt này không (nghe theo một quy trình chết)?
rustyx

12

Chúng tôi có cùng một vấn đề và đã sử dụng Process Explorer từ Microsoft Sysiternals để tra cứu ID tiến trình không còn tồn tại.

Nó chỉ ra rằng quá trình này được tham chiếu bởi một số quy trình DrWatson. Giết chết các quá trình phát hành cổng. DrWatson được sử dụng để gửi các bộ nhớ tới Microsoft và việc này mất vài giờ vì quá trình bị hỏng giữ vài chục GB bộ nhớ tại thời điểm đó.


7

Tôi nghĩ bạn nên thử CurrPorts

CurrPorts là phần mềm giám sát mạng hiển thị danh sách tất cả các cổng TCP / IP và UDP hiện đang mở trên máy tính cục bộ của bạn. Đối với mỗi cổng trong danh sách, thông tin về quy trình mở cổng cũng được hiển thị, bao gồm tên quy trình, đường dẫn đầy đủ của quy trình, thông tin phiên bản của quy trình (tên sản phẩm, mô tả tệp, v.v.), thời gian quá trình đã được tạo và người dùng đã tạo ra nó.

Ngoài ra, CurrPorts cho phép bạn đóng các kết nối TCP không mong muốn, giết quá trình mở các cổng và lưu thông tin cổng TCP / UDP vào tệp HTML, tệp XML hoặc tệp văn bản được phân định bằng tab.

Các CurrPort cũng tự động đánh dấu bằng các cổng TCP / UDP đáng ngờ màu hồng thuộc sở hữu của các ứng dụng không xác định (Ứng dụng không có thông tin phiên bản và biểu tượng)

văn bản thay thế


4
Nó hiển thị trong danh sách dưới tên quy trình "Hệ thống". Tôi đã thử nhấp chuột phải vào mục để buộc đóng cổng nhưng không có gì xảy ra.
Srekel

7

Vấn đề có thể xảy ra là quy trình của bạn đã bắt đầu một quy trình (con) khác kế thừa tay cầm ổ cắm và nó vẫn đang chạy.

Có nhiều cách khác nhau để ngăn chặn điều này, ví dụ: ProcessStartInfo.UseShellExecute = true;


1
Cảm ơn, đây là một trong những tốt. Tôi đã gọi subprocess.call(..., cwd=..., shell=True)như một trình khởi chạy ứng dụng trong một máy chủ web python, và hóa ra tôi phải giết tất cả các tiến trình con đó để giải phóng ổ cắm. Điều kỳ lạ là tôi đang sử dụng shell = True. Điều này đã làm tôi bực mình từ lâu.
Daniel F

Tôi không nghĩ rằng việc sử dụng shell sẽ dẫn đến hành vi này. Nếu bạn muốn chấm dứt tất cả các quy trình con khi cha mẹ chết, tôi nghĩ cách chính xác là tạo Đối tượng công việc với cờ JOB_OB DỰ_LIMIT_KILL_ON_JOB_CLOSE , thêm từng quy trình con với AssignProcessToJobObject và cho phép xử lý đóng tự nhiên khi xử lý cha mẹ.
qris

1

Bạn có thể thấy quá trình trong Process Explorer không? Nếu có hơn bạn có thể giết nó từ đó, nhưng chỉ sau khi bạn điều tra xem nó thực sự là gì (bạn có thể thấy tất cả các dll được tải vào quy trình)


1

Hãy thử ném cờ '-b' vào lệnh netstat của bạn. Nó sẽ cho bạn biết tên của tệp thực thi đang sử dụng cổng. Sau đó tìm thấy Proc trong trình quản lý tác vụ và giết nó ở đó. Nếu điều đó không làm việc, những gì thực thi được đang giữ cổng mở.


Tôi không thể sao chép nó vào lúc này, nhưng tôi khá chắc chắn rằng vì mọi nỗ lực (và công cụ) khác khi cố gắng tìm tên của quá trình đều thất bại, netstat cũng sẽ không thể làm được.
Srekel

1

Cần phải đề cập đến thuật ngữ nán lại đây.

Thông tin chi tiết có thể được tìm thấy tại http://msdn.microsoft.com/en-us/l Library / ms739165.aspx

Tóm lại: Có một tùy chọn yêu cầu hệ thống ổ cắm giữ cho ổ cắm mở ngay cả khi đã đóng nếu có dữ liệu chưa gửi.

Trong ứng dụng C # của bạn, bạn có thể chỉ định bất kỳ tùy chọn liên quan nào thông qua Socket.SetSocketOption: http://msdn.microsoft.com/en-us/l Library / 2011011kecd.aspx

Vì tất cả những thứ được đề cập đều liên quan đến việc gửi và ứng dụng khách, nhưng chúng tôi gặp vấn đề tương tự trong công việc, một số tìm kiếm khác đã tiết lộ rằng người ta có thể chỉ định tùy chọn nán lại cho người nghe như trong ví dụ ở đây: http://msdn.microsoft.com / l Library / system.net.sockets.tcplistener.server.aspx

Một số đồng nghiệp đã nói về các cổng được HĐH nắm giữ sau khi chấm dứt / đóng ứng dụng trong khoảng hai phút. Do đó, sẽ rất thú vị khi biết liệu cổng vẫn được giữ sau một khoảng thời gian nhất định.


Các cổng được giữ mở lâu hơn thế (không nhớ bao lâu nhưng có thể đến một giờ trước khi tôi bỏ cuộc và khởi động lại).
Srekel

Tôi không chắc liệu tùy chọn nán lại có liên quan đến trường hợp cụ thể này hay không, vì dường như nó chỉ xác định những gì sẽ xảy ra sau khi gọi tới CloseSocket. Vì tôi đang hủy ứng dụng, tôi nghi ngờ rằng hàm này được gọi (?).
Srekel

1

Tôi cũng gặp phải vấn đề này. Cuối cùng tôi đã tìm thấy lý do của mình. Nó được gây ra bởi quá trình chính đã gọi một tiến trình con bằng popen trong c / c ++. Nhưng quá trình chính sụp đổ / tắt máy trước khi gọi pclose. Sau đó, cổng sẽ xử lý quá trình chính vẫn sống và vẫn lắng nghe trên đó.


1
Tôi thấy câu trả lời này tại ServerFault hữu ích: serverfault.com/a/273727/8856
Harriv 18/12/12

1

Tôi gặp vấn đề tương tự với xdebug, nó đã mở cổng 9000.

Tôi quản lý để đóng với cmd bằng cách sử dụng "taskkill / pid xxxx".

Pid của quá trình sử dụng cổng có thể được lấy bằng "netstat -o".

Cấu hình của tôi là win 7 nhà cao cấp.


1

Tôi đã có cùng một vấn đề và khắc phục nó bằng cách:

  • tìm kiếm PID với netstat -o
  • Giết nó với tiến trình xp

Thật thú vị khi lưu ý rằng netstat đôi khi có thể trả về một pid nhưng không phải là tên thực thi tương ứng!


1

Vấn đề có thể được gây ra nếu quá trình chết đã bắt đầu một hoặc nhiều quá trình con. Nếu như

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

đã được sử dụng để bắt đầu một tiến trình con, nó phụ thuộc vào giá trị của các thẻ điều khiển thừa kế, vì vậy với

bInheritHandles = false 

Windows sẽ không chặn cổng nếu tiến trình cha bị dừng và tiến trình máy khách vẫn đang chạy.


1

Đã thấy vấn đề tương tự khi nguyên nhân gốc là một số tiến trình con được tạo kế thừa các cổng, tiến trình cha bị hỏng, trong khi tiến trình con vẫn giữ cổng. Giải quyết là xác định quá trình con vẫn chạy và dừng nó. Trong ví dụ ở đây, quy trình không tồn tại PID là 7336

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

Để dừng quá trình này:

> taskkill /f /pid 23828

Và điều này đã giải quyết vấn đề.


0

Tôi không cho rằng bạn đã cài đặt tường lửa (hoặc đã thử bất kỳ ứng dụng mạng Windows nào)?

Một số tường lửa thể hiện loại hành vi này và có thể giữ cho các cổng mở.

Nếu bạn có một cái, hãy thử vô hiệu hóa nó và sau đó khởi chạy chương trình của bạn và đóng nó và xem điều gì sẽ xảy ra.


Thật không may là một lựa chọn không may, vì tôi không có quyền kiểm soát tường lửa trên máy tính của mình.
Srekel

@Srekel - Tường lửa là gì? Khi bạn gặp vấn đề, cá nhân tôi nghĩ rằng đó là nguyên nhân gây ra vấn đề.
William Hilsum

0

Vì quy trình của bạn được liệt kê là Hệ thống, rất có thể bạn có thể giết nó trên dấu nhắc lệnh "Hệ thống". Tài khoản hệ thống có nhiều đặc quyền hơn một quản trị viên thông thường.

Bạn có thể lấy cmd.exe "Hệ thống" bằng cách lập lịch tác vụ cho cmd.exe (trình lập lịch chạy dưới dạng Hệ thống):

at 15:23 /interactive "cmd.exe" 

Thay đổi thời gian cho một cái gì đó trong tương lai gần. Hãy chắc chắn rằng bạn cũng đang ở trên bảng điều khiển máy (nếu bạn đang ở trong phiên máy chủ đầu cuối thông thường, bạn sẽ không thấy cmd.exe mới. Hãy mstscđăng nhập vào bảng điều khiển). Tôi đoán có những cách khác để làm điều đó, nhưng điều này đã làm việc cho tôi trong quá khứ.


0

Tôi có vấn đề này như nhau. Quá trình đã được gỡ lỗi trong khi nó bị sập, và vẫn còn một quá trình vsjitdebugger.exe trong trạng thái lơ lửng xung quanh, dường như đề cập đến quá trình được gỡ lỗi. Giết quá trình vsjitdebugger.exe đã giải quyết vấn đề.


0

Việc sử dụng kết hợp TCPView và Process Explorer đã làm việc cho tôi;) Trước tiên tôi tìm hiểu về id tiến trình đang sử dụng cổng trong TCPView. Cô lập quy trình trong Process Explorer và giết tiến trình bằng Process Explorer.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.