ary*_*axt 5 java sockets socketchannel
我使用选择器运行套接字.我试图检查我的套接字是否连接到服务器.
Boolean connected = _channel.isConnected();
Run Code Online (Sandbox Code Playgroud)
它总是返回true.我关闭了计算机上的机场(互联网连接),当我检查套接字是否已连接时,它仍然返回true.知道为什么吗?我尝试每3秒向服务器写一次数据,但它仍然不会将我的套接字状态更改为断开连接.
irr*_*ble 11
通常,如果关闭操作系统级网络,写入套接字应该抛出异常,因此您知道连接已断开.
但更一般地说,我们无法确定是否已传送数据包.在java(也可能是C)中,无法检查数据包是否已确认.
即使我们可以检查TCP ACK,也不能保证服务器接收或处理该数据包.它只表示目标机器接收到数据包并将其缓冲在内存中.之后很多事情都会出错.
所以,如果你真的想确定,你就不能依赖传输协议.您必须具有应用程序级别ACK,即服务器应用程序在收到并从客户端处理消息后回写ACK消息.
从客户端的角度来看,它将消息写入服务器,然后尝试从服务器读取ACK.如果它得到它,可以肯定它的消息被接收和处理.如果它没有得到确认,那么,它不知道发生了什么.根据经验,很可能TCP失败了.下一个可能性是服务器崩溃了.除了ACK无法到达客户端之外,一切都可能正常.
可以通过调用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());
}
}
Run Code Online (Sandbox Code Playgroud)
我机器上的输出是
true
false
Run Code Online (Sandbox Code Playgroud)