我正在连接打开插座的设备
要获取传入数据,我会在另一个帖子中对read
执行InputStream
操作
当我拿走我连接的对等设备的电量时,我的InputStream无法识别连接丢失。
这是我等待输入的代码:
StringBuilder sb = new StringBuilder();
String result = "";
int c;
try
{
log.info( "waiting for data..." );
while ( ( ( c = inputStream.read() ) >= 0 ) )
{
if ( c == -1 )
{
log.info( "is -1" );
}
/*
* TODO: <LF> Can't always be the delimiter to define the end of an message. This should be
* parameterized.
*/
if ( c == 0x0a /* <LF> */ )
{
result = sb.toString();
sb.delete( 0, sb.length() );
}
else if ( c != 0x0d /* <CR> */ )
{
sb.append( (char) c );
}
if ( !result.isEmpty() )
{
log.info( getName() + ": received message: " + result );
listener.MessageReceived( result.getBytes() );
result = "";
}
}
log.info( "stream ended" );
disconnect();
listener.closed();
}
catch ( IOException | ResourceException e )
{
try
{
log.info( "in catch block" );
disconnect();
listener.closed();
throw new ResourceException( "An error occured during the receiving of a message for the device, or connection timed out.", e );
}
catch ( ResourceException e1 )
{
e1.printStackTrace();
}
}
如果该信息可用于任何情况,则它位于JCA连接器内部。
据我所知,当Stream被中断时,InputStream会收到-1
,通常他应该跳转到我的stream ended
日志但不会发生。
为什么它不能识别连接无法使用,因为远程对等设备已关闭?
答案 0 :(得分:2)
正如您所说,您不希望超时,因为即使它没有发送数小时,您也需要等待对等方。除非采取特殊措施,否则不会发送数小时的同伴和已关闭的同伴之间没有区别。只要没有发送数据包,就无法检测到差异。
您可以做一件事来确保发送数据包:您可以使用Socket.setKeepAlive(true)
方法打开SO_KEEPALIVE套接字选项。
问题在于您无法从Java控制保持活动探针的发送频率。这通常取决于操作系统内核中的设置。 尽管如此,它仍然可以让您比“永远”更快地检测到死亡(或无法到达)的同伴。
答案 1 :(得分:1)
@读取超时,正如@Kayaman所建议的那样,是实现心跳的常用方法。你需要一个'timingOut'布尔值,初始化为false。每当收到任何数据,数据或心跳轮询回复时,将其设置为false。读取超时后,检查'timingOut'标志。如果为false,则发送轮询请求并将'timingOut'设置为true。如果为true,请关闭套接字并执行“连接丢失”操作。
不需要单独的线程。如果经常传输数据,不要浪费轮询。