當我重新啓動應用程序時,出現BindException。它充當等待遠程控制消息的服務器。 ServerSocket在後臺線程(AsyncTask)中運行。重新啓動我的應用程序後,我總是得到上述異常。我必須等待10分鐘,直到它再次綁定到端口才能聽取。重新啓動應用程序後出現「BindException:地址已被佔用」
我嘗試了不同的端口(全部> 50000),所以我確定沒有其他應用程序阻止我的端口。我試圖小心關閉套接字,並試圖使用SO_REUSEADDR選項。另外我確信在運行時只有一個連接打開,因爲我記錄了每個socketbind。
所以我認爲,連接沒有正確關閉。我讀過關於套接字不立即關閉的習慣。但是,在每次重新啓動應用程序時,我都等不到10分鐘,我沒有找到縮短或殺死這個時間的方法。
你有什麼想法嗎?
例外:
10-04 16:39:22.526: WARN/System.err(4974): java.net.BindException: Address already in use
10-04 16:39:22.526: WARN/System.err(4974): at org.apache.harmony.luni.platform.OSNetworkSystem.bind(Native Method)
10-04 16:39:22.526: WARN/System.err(4974): at dalvik.system.BlockGuard$WrappedNetworkSystem.bind(BlockGuard.java:275)
10-04 16:39:22.526: WARN/System.err(4974): at org.apache.harmony.luni.net.PlainSocketImpl.bind(PlainSocketImpl.java:165)
10-04 16:39:22.526: WARN/System.err(4974): at java.net.ServerSocket.<init>(ServerSocket.java:123)
10-04 16:39:22.526: WARN/System.err(4974): at java.net.ServerSocket.<init>(ServerSocket.java:74)
10-04 16:39:22.526: WARN/System.err(4974): at com.*******.remote.RemoteHandlerListener$1.doInBackground(RemoteHandlerListener.java:114)
代碼:
ServerSocket server;
try {
server = new ServerSocket();
server.setReuseAddress(true);
server.bind(new InetSocketAddress(serverport));
} catch (IOException e) {
e.printStackTrace();
return null;
}
while (true) {
BufferedReader inStream = null;
Socket client = null;
try {
client = server.accept();
inStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
// read from stream
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException e) { }
}
if (client != null) {
try {
client.close();
} catch (IOException e) { }
}
}
}
try {
server.close();
} catch (IOException e) { }
的異常在server.bind語句拋出。
編輯: 問題的原因:自接受呼叫阻塞後,線程不會自行終止。該程序沒有完全終止,並且套接字未被綁定。
解決方案:將SO_TIMEOUT設置爲套接字並在while() - 循環中檢查isCancelled。這樣,如果你調用cancel(),線程就會完成。
您可以定義「重新啓動」和「後臺線程」嗎?你是從任務管理器中殺死應用程序並重新啓動它,還是重新安裝.apk?當你說後臺線程時,你使用的是AsyncTask還是傳統的Java線程,並且它被標記爲守護進程?這些都與應用程序生命週期和虛擬機如何與併發單元一起工作。 –
通過重新啓動,我的意思是在開始活動中按下後退按鈕,然後通過單擊圖標,然後再次啓動它,從而調用onDestroy方法,在那裏停止線程。不涉及任務管理器或重新安裝。通過taskmanager殺死應用程序解決了這個問題,但並不是真正的解決方案。 –
作爲後臺線程我使用AsyncTask。 –