如何在计算机唤醒后识别MacOSX上断开的Java套接字连接
我有一个Java客户机,它应该经常连接到某个Java服务器,只输出服务器发送的任何内容(见下面的摘录) 问题是,如果客户端计算机(MacOS X)进入睡眠状态,然后再次醒来,客户端将挂起在.readLine()中的如何在计算机唤醒后识别MacOSX上断开的Java套接字连接,java,macos,sockets,sleep-mode,Java,Macos,Sockets,Sleep Mode,我有一个Java客户机,它应该经常连接到某个Java服务器,只输出服务器发送的任何内容(见下面的摘录) 问题是,如果客户端计算机(MacOS X)进入睡眠状态,然后再次醒来,客户端将挂起在.readLine()中的in,并且没有意识到连接已断开。我在套接字中添加了一个SO_TIMEOUT,这样客户端就可以停止阻塞readLine(),它确实会抛出一个SocketTimeoutException,但随后很高兴再次尝试从断开的连接中读取一行 我的问题是:为什么.readLine()中的不会因IOEx
in
,并且没有意识到连接已断开。我在套接字中添加了一个SO_TIMEOUT
,这样客户端就可以停止阻塞readLine()
,它确实会抛出一个SocketTimeoutException
,但随后很高兴再次尝试从断开的连接中读取一行
我的问题是:为什么.readLine()中的不会因IOException
而失败(这样我就可以重新启动连接),以及如何在Mac OS X上通过awake->sleep->awake
周期使客户端重新连接到服务器
Socket socket = new Socket(...);
socket.setSoTimeout(10000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
[...]
while (true) {
try {
while ((serverSays = in.readLine()) != null) {
System.out.println("Server says: " + serverSays);
}
} catch (SocketTimeoutException e) {
continue;
}
// An exception other than SocketTimeoutException will break the while-loop.
}
// If another exception other than SocketTimeoutException occurs,
// catch it and re-initiate the connection and start over.
如果需要使用超时并在套接字断开时重新连接,请尝试以下操作:
Socket socket = new Socket(...);
socket.setSoTimeout(10000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
[...]
while (true) {
try {
while ((serverSays = in.readLine()) != null) {
System.out.println("Server says: " + serverSays);
}
} catch (SocketTimeoutException e) {
continue;
} catch (IOException e) {
//reconnecting with new Socket object and new reader, because old stream closed
socket = new Socket(...);
socket.setSoTimeout(10000);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
}
如果需要使用超时并在套接字断开时重新连接,请尝试以下操作:
Socket socket = new Socket(...);
socket.setSoTimeout(10000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
[...]
while (true) {
try {
while ((serverSays = in.readLine()) != null) {
System.out.println("Server says: " + serverSays);
}
} catch (SocketTimeoutException e) {
continue;
} catch (IOException e) {
//reconnecting with new Socket object and new reader, because old stream closed
socket = new Socket(...);
socket.setSoTimeout(10000);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
}
IOException
表示本地主机知道远程主机不再提供数据
SocketTimeoutException
表示远程主机无法在分配的时间内提供数据。它从未告诉我们连接正式中断
SocketTimeoutException
在连接未正常关闭时发生。如果远程主机电源断开,或者有人从中拔出以太网电缆,这就是你得到的
在本例中,当您处于睡眠状态时,远程主机必须已决定关闭连接,但您的主机由于处于睡眠状态而错过了通知
解决方案是假设连接在一定次数的超时后断开。IOException
表示本地主机知道远程主机不再提供数据
SocketTimeoutException
表示远程主机无法在分配的时间内提供数据。它从未告诉我们连接正式中断
SocketTimeoutException
在连接未正常关闭时发生。如果远程主机电源断开,或者有人从中拔出以太网电缆,这就是你得到的
在本例中,当您处于睡眠状态时,远程主机必须已决定关闭连接,但您的主机由于处于睡眠状态而错过了通知
解决方案是假设连接在一定次数的超时后已断开。问题在于从不抛出IOException
。它只是抛出SocketTimeoutException
,然后一遍又一遍地尝试读取一行。即使我在另一端终止服务器,客户端仍会尝试读取一行(而不会抛出IOException
)。您可以尝试ping此连接。尝试向服务器发送简单数据。如果成功,则连接处于活动状态,否则关闭套接字并在我的第二个catch块中执行代码。您可以检查socket.isConnected(),但我不确定它是否有帮助。问题是从未抛出IOException
。它只是抛出SocketTimeoutException
,然后一遍又一遍地尝试读取一行。即使我在另一端终止服务器,客户端仍会尝试读取一行(而不会抛出IOException
)。您可以尝试ping此连接。尝试向服务器发送简单数据。如果成功,则连接处于活动状态,否则关闭套接字并执行第二个catch块中的代码。您可以检查socket.isConnected(),但我不确定它是否有帮助。