2010-12-16 28 views
3

我在Windows 2008x64上的一個C++應用程序出現問題(相同的應用程序在Windows 2003x64上運行得很好)。Socket在應用程序崩潰後仍在監聽

在發生崩潰或者有時在正常關機/重啓循環之後,在使用端口82上的套接字時它有問題需要接收命令。

看看netstat我看到套接字在應用程序停止後超過10分鐘仍處於監聽狀態(此過程絕對不再運行)。

TCP 0.0.0.0:82    LISTENING 

我嘗試設置套接字選項REUSEADDR但據我所知,只有影響再次連接到這是在TIME_WAIT狀態的端口。無論哪種方式,這種改變似乎沒有任何區別。

int doReuse = 1; 
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, 
      (const char *)&doReuse, sizeof(doReuse)); 

任何想法我能做些什麼來解決或至少避免這個問題?

編輯:

難道netstat的-an但是這是所有我得到:

TCP 0.0.0.0:82    0.0.0.0:0    LISTENING 

netstat的-anb我得到:

TCP 0.0.0.0:82    0.0.0.0:0    LISTENING 
[System] 

我所知道的優雅地關閉,但即使應用程序由於某種原因崩潰,我仍然需要能夠重新啓動它。有問題的應用程序使用內部使用Windows套接字API的內部庫。

編輯:

顯然有針對此問題沒有解決,所以發展我將與代理/工具來解決它去。感謝所有的建議,非常感謝。

+1

如果您在計算機重新啓動後仍有問題,可能是其他程序正在使用您的端口。做一個'netstat -anb'來看看誰在82上收聽。 – 2010-12-16 20:44:54

+1

這是崩潰後的正常現象。套接字inofrmation被保存在操作系統中(你的應用程序只是持有這些信息的句柄)。當你的應用程序崩潰時(或者在不關閉連接的情況下退出),套接字將一直保持使用狀態,直到操作系統檢測到應用程序已經失效(這可能會持續10分鐘)。您最好的選擇是通過端口作爲命令行參數,這樣您就可以在解除竊聽的同時快速更改端口。 – 2010-12-16 21:21:46

+0

在Windows事件記錄器中是否有任何錯誤消息,可能是事件ID 4227? – 2010-12-16 21:42:21

回答

2

如果這隻會在調試時傷害您,請使用sysinternals人員的tcpview強制關閉套接字。我假設它適用於您的平臺,但我不確定。

如果您正在對任何套接字執行阻止操作,請勿使用無限期超時。根據我的經驗,這可能會在多處理器機器上造成奇怪的行爲。我不確定它是什麼Windows服務器操作系統,但它是2003 Server之前的一個或兩個版本。 而不是無限期超時,使用30到60秒超時,然後重複等待。這適用於重疊的IO和IOCompletion端口,如果您正在使用它們。

如果這是一個應用程序,你運送給別人使用,祝你好運。 Windows可以使用套接字時,是一個純粹的混蛋......

+0

我能夠使用tcpview爲一個不存在的進程關閉一個連接的套接字,但不是一個監聽套接字。 – Gabe 2015-04-17 03:58:37

0

首先要檢查的是,它確實是您的應用程序在該端口上偵聽。用途:

netstat -anb

弄清楚哪些進程正在該端口上listenin。

要檢查的第二件事是,當您的應用程序關閉時,您正在優雅地關閉套接字。如果您使用的是高級套接字API,但這不應該成爲太大的問題(您使用套接字API您的,對吧?)。

最後,你的應用程序結構如何?它是否穿線?它是否啓動其他進程?你怎麼知道你的應用程序真的關閉了?

+0

增加了澄清+ netstat -anb輸出,我也用任務管理器檢查過,應用程序進程肯定不見了,它不會產生任何其他進程。 – BrokenGlass 2010-12-16 20:57:55

0

運行

的netstat -ano

這會給你有打開的端口的進程的PID。從任務管理器中檢查該進程。確保你有「從所有用戶列表進程」被選中。

+0

我打賭「系統」保持打開狀態,但我可能是錯的。 – 2010-12-17 00:34:41

+0

這是正確的「系統」保持它。 – BrokenGlass 2010-12-17 03:52:14

+0

這表示某些Windows服務將其打開,可能是間接由您的應用啓動的服務。我建議你逐個關閉正在運行的服務,並查看端口是否被釋放(或至少進入了time_wait狀態)。如果,那麼您可能想要完全禁用該服務。請張貼您的發現。 – 2010-12-17 22:55:21

1

我嘗試設置套接字選項 REUSEADDR但據我知道, 僅影響重新連接到端口 這是在TIME_WAIT狀態。

這不太正確。它將允許您重新使用處於TIME_WAIT狀態的端口用於任何目的,即偵聽或連接。但我同意這不會對此有所幫助。我感到驚訝的是,操作系統需要10分鐘才能檢測到墜毀的聽衆。它應該在流程結束時儘快清除所有資源,除了處於TIME_WAIT狀態的端口。

+0

實際上系統從未恢復,即使在幾小時後端口不可用,基本上只有重新啓動才能修復此問題 - 對於Win 2003x64,情況並非如此,因此Win 2008中的某些內容必須發生更改 – BrokenGlass 2010-12-17 03:56:36

+0

這是一個操作系統錯誤然後。將其報告給Microsoft。 – EJP 2010-12-17 04:40:37

0

http://hea-www.harvard.edu/~fine/Tech/addrinuse.html是一個很好的資源「綁定:地址已在使用」的錯誤。

一部分摘錄:

TIME_WAIT是過程完成後,通常擠佔端口幾分鐘的狀態。相關超時的長度在不同操作系統上有所不同,並且在某些操作系統上可能是動態的,但典型值在1到4分鐘的範圍內。

策略避免

SO_REUSEADDR

這是兩個最簡單的和「地址已經在使用」減少錯誤的最有效的選擇。

客戶端關閉,如果遠端啓動閉合可避免第一

TIME_WAIT。所以服務器可以通過讓客戶先關閉來避免問題。

減少超時

如果(無論何種原因),這兩種方法都不適合你,它也有可能縮短與TIME_WAIT相關的超時。