即使您的服務器沒有從客戶端「接收」,客戶端套接字上的非阻塞讀取會告訴您無法讀取任何內容(如您所期望的),或者客戶端已斷開連接。
如果您使用的是NIO,您可以簡單地使用非阻塞的Selector
循環(使用非阻塞套接字),並且只能在30秒內寫入。如果SelectionKey
可讀,並且SocketChannel
上的讀數返回-1,則您知道客戶端已斷開連接。
編輯:阻塞的另一種方法是簡單地選擇30秒超時。任何客戶端斷開連接都會導致select返回,您將通過讀取設備知道哪些客戶端會斷開連接。您需要在此處做的附加事項是跟蹤選擇中被阻止的時間,以確定何時在30秒標記上進行寫入(設置下一次選擇三角洲的超時時間)。
大編輯:交談MYN下面,提供完整的例子之後:
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
// Set a 1 second timeout on the socket
clientSocket.setSoTimeout(1000);
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
long myNextOutputTime = System.currentTimeMillis() + 30000;
String inputLine = null;
boolean connected = true;
while (connected)
{
try {
inputLine = in.readLine();
if (inputLine == null)
{
System.out.println("Client Disconnected!");
connected = false;
}
}
catch(java.net.SocketTimeoutException e)
{
System.out.println("Timed out trying to read from socket");
}
if (connected && (System.currentTimeMillis() - myNextOutputTime > 0))
{
out.println("My Message to the client");
myNextOutputTime += 30000;
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
這裏值得注意的是,PrintWriter
真正感動你遠離實際的插座上,你不會在寫入時捕獲套接字斷開連接(它永遠不會拋出異常,您必須使用checkError()
手動檢查它)您可以更改爲使用BufferedWriter
(需要使用flush()
推送輸出)並像處理它一樣處理它,以便捕獲迪斯科在寫。
+1或者,換句話說,你必須輪詢,說一秒鐘,一個非阻塞閱讀。 – 2011-03-10 17:47:44
謝謝Brian。我沒有使用NIO,是否仍然可以使用非阻塞式讀取?我也嘗試過使用'setSoTimeout()',但是當我強迫客戶端關閉時,這似乎不起作用,這是我的測試之一。 – Myn 2011-03-11 09:59:29
是否有你不使用NIO的原因?它自2002年以來一直存在,真正讓你的問題變得微不足道。我很久沒有想到我們在NIO之前如何做到這一點;查看它之前沒有一個真正的非阻塞讀取或一個'select()'。你用'setSoTimeout()'來正確的軌道,因爲這是你擁有的唯一途徑。你應該可以在你的socket讀取之前調用它,如果它超時,它會拋出一個'InterruptedIOException'。相當混亂,但 - 如果你可以使用NIO,我可以給你一個它如何工作的例子。 – 2011-03-11 15:51:56