Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SocketChannel不';检测不到断开?_Java_Sockets_Socketchannel - Fatal编程技术网

Java SocketChannel不';检测不到断开?

Java SocketChannel不';检测不到断开?,java,sockets,socketchannel,Java,Sockets,Socketchannel,我使用选择器运行一个套接字。我正在尝试检查我的套接字是否连接到服务器 Boolean connected = _channel.isConnected(); 而且它总是返回真的。我关闭了计算机上的Airport(internet连接),当我检查套接字是否已连接时,它仍然返回true。 知道为什么吗? 我尝试每3秒钟向服务器写入一次数据,但它仍然不会将套接字的状态更改为断开连接 套接字通道可以通过调用其连接方法进行连接;一旦连接,插座通道将保持连接状态,直到其关闭 由于物理连接中断或服务器故障,

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

Boolean connected = _channel.isConnected();
而且它总是返回真的。我关闭了计算机上的Airport(internet连接),当我检查套接字是否已连接时,它仍然返回true。 知道为什么吗? 我尝试每3秒钟向服务器写入一次数据,但它仍然不会将套接字的状态更改为断开连接

套接字通道可以通过调用其连接方法进行连接;一旦连接,插座通道将保持连接状态,直到其关闭

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

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


编辑

对于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

通常,如果您关闭操作系统级网络,对套接字的写入将引发异常,这样您就知道连接已断开

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

即使我们可以检查TCP确认,也不能保证服务器接收或处理数据包。这只意味着目标机器接收到数据包并将其缓冲在内存中。在那之后,很多事情可能会出错

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


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

isConnected()告诉您是否连接了通道对象,您已经连接了通道对象,并且没有指定在关闭通道对象后返回false,尽管显然是这样:请参阅Andreas的回答。它不是用来告诉您底层连接是否仍然存在。你只能通过使用它来判断这一点:阅读中的-1或例外情况告诉你这一点。

我很困惑,有人一直在更改我问题的标题。这是怎么回事?通过上面的代码,您可以检查SocketChannel是否仍然连接。那么,您到底测试了什么,问题中提到的套接字,还是标题中描述并在代码中显示的频道?只是问,因为人们开始否决我的答案。。。(没有解释为什么…)1-通过调用方法手动关闭套接字,这就是为什么在断开与服务器的连接后出现错误,在我的情况下,我试图检测是否存在断开连接问题,例如“连接丢失”,因此,套接字不会检测到它已断开连接,除非我尝试向服务器发送消息并获得异常。2-我还提到我正在使用选择器。因此isConnected方法不显示我是否连接到服务器,但它显示我的套接字是否仍连接到选择器,只要我的套接字连接到选择器
isConnected()
在我关闭到远程服务器的通道时,在我的机器上返回
false
。请参阅我的答案以获得一个有效的示例。
-1
from read也不起作用。我添加了一个read,它被阻塞(等待字节)。然后我拔下网络电缆,应用程序一直阻塞(结果是no
-1
)。是的,read中的-1检测到有序关闭。只有通过读取超时,才能检测到有读无写的无序关闭,这会产生异常。亲爱的投票人-如果你认为答案没有帮助,请留下评论。至少EJP的评论是不正确的,因为他的回答。。。问题是关于SocketChannels的,我仍然确信,这解释了为什么关闭机场不会导致
isConnected()==false
。我同意安德烈亚斯的观点:无法解释的否决票是无用的,或者更糟。我开始将无法解释的否决票视为纯粹的网站破坏行为。