关于java socket 关闭的思考.

你很难侦测到连接是否有断开:

/**
 * 
 * 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断开连接

为啥不能优雅的检查socket是否可用(不下发IO时)

点击打开链接

 

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.

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值