我使用以下代码让我的服务器在连接后继续监听客户端消息。
在监听时,我想检测客户端是否在 read
时断开连接。值变为-1
并完成了WhileLoop
.
private volatile boolean isConnected = true;
//....
while(isConnected){ //Whe it comes to false then Receiving Message is Done.
try {
socket.setSoTimeout(10000); //Timeout is 10 Seconds
InputStream inputStream = socket.getInputStream();
BufferedInputStream inputS = new BufferedInputStream(inputStream);
byte[] buffer = new byte[256];
int read = inputS.read(buffer);
String msgData = new String(buffer,0,read);
//Detect here when client become disconnected
if(read == -1){ //Client become disconnected
isConnected = false;
Log.w(TAG,"Client is no longer Connected!");
}else{
isConnected = true;
Log.w(TAG,"Client Still Connected...");
}
//....
}catch (SocketException e) {
Log.e(TAG,"Failed to Receive message from Client, SocketException occured => " + e.toString());
}catch (IOException e) {
Log.e(TAG,"Failed to Receive message from Client, IOException occured => " + e.toString());
}catch (Exception e) {
Log.e(TAG,"Failed to Receive message from Client, Exception occured => " + e.toString());
}
}
Log.w(TAG, "Receiving Message is Done.");
上面的代码适用于接收消息,但我在检测客户端何时断开连接时遇到问题。
当客户端断开连接时,会发生异常并出现以下错误:java.lang.StringIndexOutOfBoundsException: length=256; regionStart=0; regionLength=-1
和 WhileLoop
没有按预期完成。
我假设当客户端断开连接时会发生这种情况 if(read == -1){....}
。
我刚刚找到了这个post在搜索时,EJP的答案给了我read() returns -1
上的最佳解决方案,但我才刚刚开始 ServerSocket
所以我不知道我这样做是否正确。
最佳答案
String msgData = new String(buffer,0,read);
如果read
为-1,它将抛出异常。我完全希望如此。
只需将该行移动到您的 else
分支,在其中检查 read 是否为 -1,这样只有在实际存在数据时才会构造字符串。
参见:https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#String-byte:A-int-int-
Throws: IndexOutOfBoundsException - If the offset and the length arguments index characters outside the bounds of the bytes array
-1 长度超出范围:)
关于java - ServerSocket检测客户端断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40124659/