TCP长连接与NAT超时

2023-10-27

TCP长连接

  • TCP连接建立后只要不关闭,逻辑上连接一直存在。
  • TCP是有保活定时器的,可以打开保活定时器来维持长连接,设置SO_KEEPALIVE才会开启,时间间隔默认7200s,也就是2h,这个默认是关闭的。
  • HTTP中的keep-alive和TCP中的keepalive的原理不一样

NAT超时

因为 IP v4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯。

大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT 表中的对应项,造成链路中断。

长连接心跳间隔必须要小于NAT超时时间(aging-time),如果超过aging-time不做心跳,TCP长连接链路就会中断,Server就无法发送Push给手机,只能等到客户端下次心跳失败后,重建连接才能取到消息。

NAT设备会在IP封包通过设备时修改源/目的IP地址. 对于家用路由器来说, 使用的是网络地址端口转换(NAPT), 它不仅改IP, 还修改TCP和UDP协议的端口号, 这样就能让内网中的设备共用同一个外网IP. 举个例子, NAPT维护一个类似下表的NAT表:

内网地址 外网地址
192.168.0.2:5566 120.132.92.21:9200
192.168.0.3:7788 120.132.92.21:9201
192.168.0.3:8888 120.132.92.21:9202

NAT设备会根据NAT表对出去和进来的数据做修改,比如将192.168.0.3:8888发出去的封包改成120.132.92.21:9202,外部就认为他们是在和120.132.92.21:9202通信。同时NAT设备会将120.132.92.21:9202收到的封包的IP和端口改成192.168.0.3:8888,再发给内网的主机,这样内部和外部就能双向通信了,但如果其中192.168.0.3:8888 == 120.132.92.21:9202这一映射因为某些原因被NAT设备淘汰了,那么外部设备就无法直接与192.168.0.3:8888通信了。
  国内移动无线网络运营商在链路上一段时间内没有数据通讯后,会淘汰NAT表中的对应项, 造成链路中断。

心跳包

  • 心跳的原因:虽然理论tcp连接后一直不断,但实际上会断网。见:比如 NAT超时,更多
    影响TCP连接寿命的因素
  • 心跳包的主要作用是告知对方连接端,我还活着,心还在跳。
  • 心跳时长多少?
    现实是残酷的, 根据网上的一些说法, 中移动2/3G下, NAT超时时间为5分钟, 中国电信3G则大于28分钟, 理想的情况下, 客户端应当以略小于NAT超时时间的间隔来发送心跳包。
地区/网络 NAT超时时间
中国移动3G和2G 5分钟
中国联通2G 5分钟
中国电信3G 大于28分钟
美国3G 大于28分钟
台湾3G 大于28分钟

wifi下,NAT超时时间都会比较长,据说宽带的网关一般没有空闲释放机制, GCM有些时候在wifi下的心跳比在移动网络下的心跳要快,可能是因为wifi下联网通信耗费的电量比移动网络下小。

心跳包和轮询的区别

心跳包和轮询看起来类似,都是客户端主动联系服务器,但是区别很大:

  • 轮询是为了获取数据, 而心跳是为了保活TCP连接
  • 轮询得越频繁, 获取数据就越及时, 心跳的频繁与否和数据是否及时没有直接关系
  • 轮询比心跳能耗更高, 因为一次轮询需要经过TCP三次握手, 四次挥手, 单次心跳不需要建立和拆除TCP连接

参考:
关于TCP长连接,NAT超时,心跳包
NAT(Network Address Translation)
HTTP keep-alive和TCP keepalive的区别,你了解吗?
TCP中已有SO_KEEPALIVE选项,为什么还要在应用层加入心跳包机制??

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TCP长连接与NAT超时 的相关文章

  • Android 中多个蓝牙连接的自定义 UUID

    我有一个 Android 设备作为服务器连接到多个蓝牙 Android 客户端 我了解 UUID 的概念以及它的独特之处 我的问题是 我可以为连接到我的服务器的所有客户端使用相同的 UUID 吗 如果没有 我如何以编程方式为我的客户端生成
  • gradle更新后无法找到方法(无法编译项目)

    我尝试将项目中的 gradle 版本更新为 4 1 milestone 1 以下这些说明 https developer android com studio build gradle plugin 3 0 0 migration html
  • 如何获取每个StorageVolume的可用大小和总大小?

    背景 谷歌 悲伤 计划破坏存储权限 https www xda developers com android q storage access framework scoped storage 这样应用程序将无法使用标准文件 API 和文件
  • 我在布局上看不到任何 FirebaseRecyclerAdapter 项目

    我试图将数据从 Firebase 数据库检索到我的布局 但我看不到任何项目FirebaseRecyclerAdapter在布局中 请帮忙 我按照一个教程展示了如何做到这一点 当我运行应用程序时 我没有看到任何项目 但我可以滚动 public
  • 从响应中获取标头(Retrofit / OkHttp 客户端)

    我正在使用 Retrofit 与 OkHttp 客户端和 Jackson 进行 Json 序列化 并希望获取响应的标头 我知道我可以扩展 OkClient 并拦截它 但这发生在反序列化过程开始之前 我基本上需要的是获取标头以及反序列化的 J
  • Android应用程序组件销毁和重新创建的详细信息

    有人可以向我提供一些具体的 值得信赖的 最好是简洁的 信息 内容如下 系统销毁和 如果适用 重新创建组件的顺序 片段 活动 活动的线程 异步任务 计时器 静态数据 类何时卸载 其他类中的线程 异步任务 定时器 主机 TabActivity
  • Bitmap.getPixels() 中的 IllegalArgumentException

    我想将数据从位图复制到int using getPixels 这是我当前的代码 int pixels new int myBitmap getHeight myBitmap getWidth myBitmap getPixels pixel
  • Dialog.setTitle 不显示标题

    我正在尝试向我的对话框添加自定义标题 但是每当我运行我的应用程序时 它都不会显示标题 我创建对话框的代码是 final Dialog passwordDialog new Dialog this passwordDialog setCont
  • 在 Cordova 应用程序中获取额外功能

    我们有两个 Android 应用程序 一个使用本机 Java 实现 另一个使用 Ionic 编写 Ionic 应用程序启动我的应用程序 这是使用灯插件 https github com lampaa com lampa startapp 我
  • Android 深度链接至 Instagram 应用

    Instagram 已经发布了 iOS 深层链接的 url 方案 但尚未为 Android 创建文档 有没有办法深入链接到 Android 上的 Instagram 应用程序 以转到 Instagram 应用程序中的特定位置 例如 Inst
  • 当它的父级是 ConstraintLayout 时设计 CardView 吗?

    我在编辑包含Relativelayout的Cardview内的RelativeLayout时搞砸了 ConstraintLayout会将相对布局的wrap content更改为0并添加工具 layout editor absoluteX 1
  • 在 android 中建立与 MySQL 的池连接

    我需要从我的 Android 应用程序访问 MySQL 数据库 现在所有的工作都通过 DriverManager getConnection url 等等 但我必须从多个线程访问数据库 所以我必须使用连接池 问题1 是 com mysql
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • 使用片段时应用程序崩溃

    我正在处理碎片和 我的代码中有一个我找不到的问题 logcat 指向我的一个片段中的这段代码 Override public View onCreateView LayoutInflater inflater ViewGroup conta
  • 对于一个单元格,RecyclerView onBindViewHolder 调用次数过多

    我正在将 RecyclerView 与 GridLayoutManager 一起使用 对于网格中的每个项目 我需要调用 REST api 来检索数据 然后 从远程异步获取数据后 我使用 UIL 加载 显示图像 一切似乎都很好 但我发现 on
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • Android 如何将总天数准确更改为年、月、日?

    我正在做一个应用程序 该应用程序与根据给定的生日日期输入获取一个人的年龄有关 为此 我从下面的代码中获取从该日期到当前日期的总天数 String strThatDay 1991 05 10 SimpleDateFormat formatte
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • 没有支持 FEATURE_CAMERA_EXTERNAL 的 Android 设备

    根据this doc https source android com devices camera external usb cameras一些 Android 设备允许使用 Camera2 API 访问外部 USB 摄像头 我检查了大约
  • 在 Android 应用程序资源中使用 JSON 文件

    假设我的应用程序的原始资源文件夹中有一个包含 JSON 内容的文件 我如何将其读入应用程序 以便我可以解析 JSON See 开放原始资源 http developer android com reference android conte

随机推荐

  • 动态规划算法的优化技巧

    关键词 动态规划 时间复杂度 优化 状态 摘要 动态规划是信息学竞赛中一种常用的程序设计方法 本文着重讨论了运用动态规划思想解题时时间效率的优化 全文分为四个部分 首先讨论了动态规划时间效率优化的可行性和必要性 接着给出了动态规划时间复杂度
  • java中实现域名解析

    import java net public class Kkkk public static void main String args throws Exception InetAddress address InetAddress g
  • 攻防世界-CTF小白-WEB(新手)

    我会一题一题的做 因为也是新手所以我会尽可能的写的清楚明白 后面所需要的工具我会慢慢发出来 也可以私信我 web新手区 1 view source X老师让小宁同学查看一个网页的源代码 但小宁同学发现鼠标右键好像不管用了 这一题够简单的了
  • 分布式锁问题_演示问题

    通过idea创建两个服务 启动Nginx服务 下载Nginx windows服务 官网nginx download 当然我这里提供了 我们打开nginx的conf目录 然后打开配置文件nginx conf进行配置 upstream test
  • 算法环境配置4_实例分割SOLOv2

    文章目录 一 环境配置 前言 0 我的环境 仅供参考 1 创建虚拟环境 2 激活虚拟环境 3 安装cuda torch torchvision toraudio 4 检查是否安装OK 5 安装预建的 Detectron2 仅限 Linux
  • dpvs入门实践1--概念及编译安装

    DPVS是一种基于DPDK的高性能四层负载均衡器 它来源于Linux Virtual Server LVS及其修改后的alibaba LVS 那LVS是什么呢 Linux Virtual Server是构建在实服务器集群上的高度可伸缩和高可
  • WSL删除文件后,Windows未释放空间

    How to Shrink a WSL2 Virtual Disk 进入powershell diskpart select vdisk file F WSL Ubuntu ext4 vhdx compact vdisk
  • js中的定时器、延时器

    一 定时器 创建定时器 window setInterval 方法名 间隔时间 1000 1秒 var timer window setInterval func1 2000 var i 0 function func1 console l
  • C++函数对象

    目录 函数符概念 函数对象 函数对象 函数指针调用演示 匿名函数Lambda 函数包装器 函数符概念 两大类 函数对象 函数指针 四种形式 函数对象 成员函数指针 全局函数指针 Lambda表达式 函数对象 函数对象概念 1 函数对象是一个
  • 中国电子学会2022年09月份青少年软件编程Python等级考试试卷二级真题(含答案)

    2022 09 Python二级真题 分数 100 题数 37 测试时长 60min 一 单选题 共25题 共50分 1 运行以下代码 结果输出的是 C 2分 means Thank You print len means A 8 B 6
  • 最粗暴的方法实现一个栈

    对于栈和队列是一个很简单的知识 用的感觉也不是很多 但是 我们仍然的学习 加油 在实现最简单的栈之前 我们需要简单了解一下栈是什么 栈 stack 又名堆栈 它是一种运算受限的线性表 限定仅在表尾进行插入和删除操作的线性表 这一端被称为栈顶
  • 数据结构图的操作邻接表创建,深度、广度遍历,Dijkstra最短路径算法

    邻接表 深度优先 广度优先搜索方式遍历图 include
  • 数值计算之 插值法(1)多项式插值——拉格朗日插值法

    数值计算之 插值法 1 多项式插值 拉格朗日插值法 前言 什么是插值 多项式插值法 拉格朗日插值法 总结 前言 移动机器人有一个非常重要的任务 轨迹规划 轨迹规划需要满足运动学原理 即在路径规划给出路点后 必须把路点平滑成光滑的轨迹 才能让
  • 对输入图像按比例压缩、居中填充

    摘要 图像在输入神经网络之前 通常需要进行尺寸压缩 如yolov5的输入为640x640 分类网络Resnet 50的输入为224x224 通常地 分类网络直接将输入进行resize处理 而对于目标检测网络 为了防止目标变形 通常采用pad
  • gitlab在merge request 中可能遇到的问题

    1 merge request 中代码冲突 merge的时候 可能存在代码冲突 这时 开发者可从远程仓库master分支重新拉取最新代码进行本地merge 解决冲突后重新提交代码进行review git pull upstream mast
  • sonar 规则总结

    bug类型 1 equals should not be used to test the values of Atomic classes bug 主要 不要使用equals方法对AtomicXXX进行是否相等的判断 Atomic变量永远
  • echarts 省市区联动地图

    地图效果 省地图
  • Java导出Excel 复杂表头

    文章标题 导出表格 依赖 导出表格 导出表格的方式在我的理解有两种 一种是直接用代码控制表头 简单的表头 一种是直接使用模板直接添加数据就可以 复杂的表头 依赖
  • Centos SSh端口号的更改

    前言 开启某服务或软件的端口 要从该服务或软件监听的端口 多以修改配置文件为主 SeLinux和防火墙 FireWall 的安全策略下手 如果使用阿里云 腾讯等第三方服务器还需要对管理控制台的安全组下手 下面进入主题 如果有什么问题请查看下
  • TCP长连接与NAT超时

    TCP长连接 TCP连接建立后只要不关闭 逻辑上连接一直存在 TCP是有保活定时器的 可以打开保活定时器来维持长连接 设置SO KEEPALIVE才会开启 时间间隔默认7200s 也就是2h 这个默认是关闭的 HTTP中的keep aliv