谈谈TCP连接状态的判定

尽管TCP和UDP都使用相同的网络层(IP),TCP却向应用层提供与UDP完全不同的服务。
TCP提供一种面向连接的、可靠的字节流服务。

TCP协议介绍

面向连接意味着两个使用 TCP的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个TCP连接。这一过程与打电话很相似,先拨号振铃,等待对方摘机说“喂”,然后才说明是谁。

TCP提供的连接是可靠的,TCP通过超时重发、接收确认、全体检验和、重排序和丢弃重复等手段,在不可靠的网络层的IP协议基础上实现了可靠的传输。

TCP的长连接

在TCP的协议里面的描述,连接一旦建立起来,如果不主动发送FIN信号,这个通道会一直保留。并且,结束还需要四次握手才能彻底拆除当前的TCP通道。

上面的一切都是建立在理想情况下,TCP的协议规定。实际情况往往十分复杂,比如网络的突然中断,设备突然断电等等,这些都会导致TCP的非正常中断,所以在实际的应用当中,判定当前TCP的连接状态显得十分的重要。

通过Socket API判定连接状态

在实际的变成当中,TCP连接的实现一般都是采用的Socket的方式实现。关于这方面的知识我不做过多的介绍。大家可以参阅相关的资料。随便一搜都是大把的资料

JAVA的Socket类当中并没有提供直接的接口,用于判定当前的连接状态。
1、isConected(),主要用于判定你是否成功连接过,如果你最近成功连接上,那么就会返回 true 。而当前的连接可能因为某些原因,已经中断了。
2、isClosed(), 这个接口仅仅能判定你是否关闭了这个Socket,只要你不关闭Socket,一直会返回false。

上面这两个方法都不能确定,当前的TCP连接的状态。

那么我们应该如何判定当前的通道状态呢?其实有一个简单的方法,那就是发送一些数据,如果能够发送成功就说明当前的连接没有问题。这是最直接,同时也是我们最常使用的一种方法。
不管因为什么原因,导致当前通道中断,Socket的写操作都会抛出一个IOExeption,使用读的方式同样能达到相同的效果。

这样就可以在捕获了的异常里面进行TCP通道的重建操作。
不给代码的行为都是耍流氓。下面给出Client端的代码。

/**
 * Created by Kiplening 3/9/2016.
 */
public class Client {
    public static void main(String[] args)  {
        Socket socket = null;
        try {
            socket = new Socket("192.168.1.129", 8000);
        } catch (IOException e) {
            e.printStackTrace();
        }

        OutputStream os = null;
        try {
            os = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (true){
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(System.in));

            String line = null;
            try {
                line = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                os.write(line.getBytes());
            } catch (IOException e) {
                System.out.println("连接中断!尝试重连。。。");
                //todo: 重连操作
                //e.printStackTrace();

            }
        }   
    }
}

代码测试结果

在双端正常工作时,可在客户端输入内容发送。一旦服务器断网,或者关掉服务程序。此时只要不发送内容,整个程序没有任何异常,一旦发送内容,便会抛出IOExcption。提示你重新建立连接。
这里写图片描述

关于上面提到的isConnected()和isClosed()方法的测试我就不做了,大家可以自己去验证下。

StackOverflow

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值