你很难侦测到连接是否有断开:
/**
*
* created by: gaoxingliang@outlook.com
* created:2015年10月15日
*/
package io.study;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;
/**
* @author gxl
*
*/
public class HowSocketWorks
{
private static final CountDownLatch c = new CountDownLatch(1);
/**
* @param args
*/
public static void main(String[] args)
{
new Thread(new MyServer()).start();
new Thread(new MyClient()).start();
}
}
class MyServer implements Runnable
{
public void run()
{
try
{
final ServerSocket ss = new ServerSocket(12345);
final Socket cs = ss.accept();
System.out.println("Accepted connection");
Thread.sleep(5000);
cs.close();
System.out.println("Closed connection");
ss.close();
Thread.sleep(100000);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
class MyClient implements Runnable
{
public void run()
{
long start = System.currentTimeMillis();
try
{
final Socket s = new Socket("localhost", 12345);
for (;;)
{
System.out.println("connected: " + s.isConnected()
+ ", closed: " + s.isClosed());
//试试不写数据 你会发现关闭后还是一直检测正常
// s.getOutputStream().write(new byte[100]);
// System.out.println("Data writed");
Thread.sleep(10000);
}
}
catch (Exception e)
{
e.printStackTrace();
// TODO: handle exception
long end = System.currentTimeMillis();
System.out.println("After " + (end -start) / 1000 + " we find it's disconnected.");
}
}
}
connected: true, closed: false
Accepted connection
Closed connection
connected: true, closed: false
connected: true, closed: false
connected: true, closed: false
connected: true, closed: false
connected: true, closed: false
connected: true, closed: false
connected: true, closed: false
如果你不试图写入数据那么 你可能需要很久才会发现已经断掉了.
如果你马上写入数据会立刻收到失败.
但是更加奇怪的是 ,你如果马上拔掉网线,你并不会马上收到错误,或者很久都不会.
参考: 如何检测socket断开连接
You have discovered that you need timers, and heartbeat on a TCP connection.
If you unplug the network cable, the TCP connection may not be broken. If you have nothing to send, the TCP/IP stack have nothing to send, it doesn't know that a cable is gone somewhere, or that the peer PC suddenly burst into flames. That TCP connection could be considered open until you reboot your server years later.
Think of it this way; how can the TCP connection know that the other end dropped off the network - it's off the network so it can't tell you that fact.
Some systems can detect this if you unplug the cable going into your server, and some will not. If you unplug the cable at the other end of e.g. an ethernet switch, that will not be detected.
That's why one always need supervisor timers(that e.g. send a heartbeat message to the peer, or close a TCP connection based on no activity for a given amount of time) for a TCP connection,
One very cheap way to at least avoid TCP connections that you only read data from, never write to, to stay up for years on end, is to enable TCP keepalive on a TCP socket - be aware that the default timeouts for TCP keepalive is often 2 hours.