前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP长链接介绍

TCP长链接介绍

作者头像
提莫队长
发布2020-06-03 10:17:18
1.3K0
发布2020-06-03 10:17:18
举报
文章被收录于专栏:刘晓杰刘晓杰

1.定义

TCP连接以后不主动断开连接.区别于短链接(三次握手四次分手算一次短链接),优点是避免短时间内重复连接所造成的信道资源以及网络资源的浪费

2.长连接断开的原因

代码语言:javascript
复制
进程被杀死
NAT超时
网络状态发生变化
其他不可抗因素(网络状态差、DHCP的租期等等 )

其中重点讲一下NAT(地址转换技术) https://blog.csdn.net/gui951753/article/details/79593307 总结一句话就是。多个私网ip地址通过端口号映射到一个公网ip地址进行通信. 但是这么做有个弊端:破坏了IP的端到端通信 为了维持这种映射关系必然需要一张映射表,在会话静默的这段时间,NAT网关会进行老化操作(节省资源),那么TCP连接很有可能断开,这就和长链接冲突

3.维持长链接方法

代码语言:javascript
复制
进程保活
心跳保活
断线重连
进程保活

进程保活

心跳保活

后面会讲

断线重连

监测到网络变化并且判断连接的有效性,如果失效,那么就重新连接(判断连接的有效性主要存在于心跳保活机制,所以下面会在心跳保活机制中一起讲)

4.心跳保活机制

心跳保活

(注意,心跳机制和轮询机制还是有区别的.心跳机制是在一个TCP连接上进行的,轮询是每隔一段时间进行一次TCP请求)

心跳机制的理论方案

理论方案

从上图可以看出,对于心跳机制方案设计的要点在于

代码语言:javascript
复制
心跳包的规格(内容 & 大小)
心跳发送的间隔时间
断线重连机制 (核心 = 如何 判断长连接的有效性)
心跳包的规格

心跳包 = 1个携带少量信息 & 大小在10字节内的信息包

间隔时间

不宜太长不宜太短.太短会有信令风暴,太长会误判成连接断开

重连

判断长连接是否有效的准则 = 服务器是否返回心跳应答 (分清存活和有效,存活仅仅表示没断开,可能阻塞无法发送接收,有效表示没断开且能正常通信)

额外说明:

TCP 协议自带 KeepAlive 的机制是否可替代心跳机制 无法替代.原因:TCP KeepAlive机制 的作用是检测连接的有无(死活),但无法检测连接是否有效。 “连接有效”的定义 = 双方具备发送 + 接收消息的能力

6.demo展示 (伪代码)

代码语言:javascript
复制
public class NativeTcpClient {

    /**
     * 保存发送的tcp指令集
     */
    private final Map<Long, CommandEntry> callbackPool = new ConcurrentHashMap<Long, CommandEntry>();

    /**
     * 处理完网络后,真正处理数据的队列
     */
    private final LinkedBlockingQueue<ResultEntry> mResultProcessedQueue = new LinkedBlockingQueue<ResultEntry>();

    private NativeTcpClient() {
        //启动线程做超时检查
        new Thread(new TimeOutRunnable()).start();//每隔1s从callbackPool取数据看是否超时,超时就删除(NativeClient如果处理掉的话会poll掉)
        /**
         * 每发送一次tcp请求,NativeClient都会处理,并且从callbackPool中移除,如果没移除,要么还没处理到,要么超时
         * 所以每次从callbackPool取数据,发送时间和当前时间的差只要超过一定时间,就可以认为是超时(30s)
         */

        mResultProcessedThread = new HandlerThread("ResultProcessedThread");
        mResultProcessedThread.start();
        Handler handler = new Handler(mResultProcessedThread.getLooper());
        handler.post(new ResultProcessedRunnable());//从mResultProcessedQueue取出数据进行notify,然后根据类型由不同的通知去处理
        NativeClient.getInstance().addMessageListener(msgListener);//最终把NativeClient返回的数据放到mResultProcessedQueue里面
        /**
         * NativeClient类似于socket功能
         * 当能成功返回数据的时候,就会通过这个listener把对应数据放到mResultProcessedQueue里面去.
         * ResultProcessedRunnable会去取mResultProcessedQueue里面的数据进行处理
         */
    }
}

整理自 https://www.jianshu.com/p/580145bbd9fe

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.定义
  • 2.长连接断开的原因
  • 3.维持长链接方法
  • 4.心跳保活机制
  • 6.demo展示 (伪代码)
  • 整理自 https://www.jianshu.com/p/580145bbd9fe
相关产品与服务
NAT 网关
NAT 网关(NAT Gateway)提供 IP 地址转换服务,为腾讯云内资源提供高性能的 Internet 访问服务。通过 NAT 网关,在腾讯云上的资源可以更安全的访问 Internet,保护私有网络信息不直接暴露公网;您也可以通过 NAT 网关实现海量的公网访问,最大支持1000万以上的并发连接数;NAT 网关还支持 IP 级流量管控,可实时查看流量数据,帮助您快速定位异常流量,排查网络故障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档