Java SocketChannel没有检测到断开连接?

时间:2010-08-14 20:24:56

标签: java sockets socketchannel

我使用选择器运行套接字。我正在尝试检查我的套接字是否已连接到服务器。

Boolean connected = _channel.isConnected();

并且它总是返回true。我关闭了计算机上的机场(互联网连接),当我检查套接字是否已连接时,它仍然返回true。 知道为什么吗? 我尝试每3秒向服务器写一次数据,但它仍然不会将我的套接字状态更改为断开连接。

3 个答案:

答案 0 :(得分:11)

通常,如果关闭操作系统级网络,写入套接字应该抛出异常,因此您知道连接已断开。

但更一般地说,我们无法确定是否已发送数据包。在java(也可能是C)中,无法检查数据包是否已确认。

即使我们可以检查TCP ACK,也不能保证服务器收到处理该数据包。它只表示目标机器接收到数据包并将其缓冲在内存中。之后很多事情都会出错。

所以如果你真的想确定,你就不能依赖传输协议。您必须具有应用程序级别ACK ,即服务器应用程序在收到处理来自客户端的消息后回写ACK消息。

从客户端的角度来看,它会将消息写入服务器,然后尝试从服务器读取ACK。如果它得到它,可以肯定它的消息是处理的。如果它没有得到确认,那么,它不知道发生了什么。根据经验,很可能TCP失败了。下一个可能性是服务器崩溃了。除了ACK无法到达客户端之外,一切都可能正常。

答案 1 :(得分:5)

  

可以通过调用connect方法连接套接字通道;连接后,插座通道保持连接状态,直到它关闭。

当服务器不再可用时,由于物理连接中断或服务器故障,通道未关闭。因此,一旦建立了连接,isConnected()将返回true,直到您关闭旁边的频道。

如果要检查,如果服务器仍然可用,则向套接字输出流发送一个字节。如果出现异常,则服务器不可用(连接丢失)。


修改

EJP的

- 测试和重新考虑您的评论和答案的一些代码:

public class ChannelTest {
     public static void main(String[] args) throws UnknownHostException, IOException {
      Socket google = new Socket(InetAddress.getByName("www.google.com"), 80);
      SocketChannel channel = SocketChannel.open(google.getRemoteSocketAddress());
      System.out.println(channel.isConnected());
      channel.close();
      System.out.println(channel.isConnected());
    }
}

我的机器上的输出是

true
false

答案 2 :(得分:4)

isConnected()告诉您是否已经连接了 channel 对象,并且在关闭它之后没有指定它返回false,尽管它显然是:看安德烈亚斯的回答。它不是告诉你基础连接是否仍然存在。你只能通过使用它来说明:-1来自读取或异常,告诉你。