我使用选择器运行套接字。我正在尝试检查我的套接字是否已连接到服务器。
Boolean connected = _channel.isConnected();
并且它总是返回true。我关闭了计算机上的机场(互联网连接),当我检查套接字是否已连接时,它仍然返回true。 知道为什么吗? 我尝试每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来自读取或异常,告诉你。