TCP的socket本身就是长连接的,那么为什么还要心跳包呢?

  在smack里有个30s发送一个空消息的线程,同样关于心跳包(keepalive)

  据网络搜索到的资料解释如下

  1. 内网机器如果不主动向外发起连接,外网机没法直连内网的,这也是内网机安全的原因之一,又因为路由器会把这个关系记录下来,但是过一段时间这个记录可能会丢失 ,所有每一个客户端每隔一定时间就会向服务器发送消息,以保证服务器可以随时找到你,这东西被称为心跳包。
  2. 理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的数据清理,重新连接……当然,这个自然是要由逻辑层根据需求去做了。总的来说,心跳包主要也就是用于长连接的保活和断线处理。一般的应用下,判定时间在30-40秒比较不错。如果实在要求高,那就在6-9秒。
  3. 如果不主动关闭socket的话,系统不会自动关闭的,除非当前进程挂掉了,操作系统把占用的socket回收了才会关闭。为什么需要心跳连接主要是判断当前连接是否是有效的、可被使用的。在实际应用中假设一段时间没有数据传输时候理论上说应该连接是没有问题的,但是网络复杂,中途出现问题也是常见的,网线被掐断了、对方进程挂掉了、频繁丢包等,这时候TCP连接是不可使用的,但是对于应用层并不知道,如果需知道网络情况则要很复杂的超时进行了解,TCP从底层就实现了这样的功能。心跳机制是TCP在一段时间间隔后发送确认连接端是否还存在,如果存在的话就会回传一个包确定网络有效,如果心跳包有问题,则通知上层应用当前网络有问题了。 
  4. 这取决于你的server端的超时配置, 每个socket连接都是长连接,它是一个相当占用系统资源的通信管道, 如果这个长连接什么事也没干硬是要占着资源,则server端可以选择关闭这个连接,以省下资源让更多的用户连接进来。
  5. 所以,即便客户端的是采用死循环while(true)方式连到服务端,对于特定的客户端和服务端类型来说也需要一定时间间隔的心跳(告诉服务端,我还活着,虽然我没干活也没说话,但别把我关了) 

  以前开发手机游戏时,索爱有一款手机有强制要求,客户端如果超过三分钟无消息发向网络服务端,则会在客户端自动地强制把socket关断。因为socket长连接相对于手机这样资源少的设备来说是宝贵的资源。  (这个强制是指客户端系统自动关的,不是我们代码close的)

  1. 在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE。系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。
  2. 心跳包一般来说都是在逻辑层发送空的echo包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。
  3. 其实,要判定掉线,只需要send或者recv一下,如果结果为零,则为掉线。

  以下是Smack里发送心跳包的代码:PacketWrite.java

void startKeepAliveProcess()
{  int keepAliveInterval = SmackConfiguration.getKeepAliveInterval();  if (keepAliveInterval > 0) {  KeepAliveTask task = new KeepAliveTask(keepAliveInterval);  this.keepAliveThread = new Thread(task);  task.setThread(this.keepAliveThread);  this.keepAliveThread.setDaemon(true);  this.keepAliveThread.setName("Smack Keep Alive (" + this.connection.connectionCounterValue + ")");  this.keepAliveThread.start();  }
}  private class KeepAliveTask implements Runnable
{  private int delay;  private Thread thread;  public KeepAliveTask(int paramInt)  {  this.delay = paramInt;  }  protected void setThread(Thread thread) {  this.thread = thread;  }  public void run()  {  try  {  Thread.sleep(15000L);  }  catch (InterruptedException localInterruptedException)  {  }  while ((!(PacketWriter.this.done)) && (PacketWriter.this.keepAliveThread == this.thread)) {  synchronized (PacketWriter.this.writer)  {  if (System.currentTimeMillis() - PacketWriter.this.lastActive >= this.delay) {  try {  PacketWriter.this.writer.write(" ");  PacketWriter.this.writer.flush();  }  catch (Exception localException)  {  }  }  }  try  {  Thread.sleep(this.delay);  }  catch (InterruptedException localInterruptedException1)  {  }  }  }
}  

View Code

  另外记一个CSDN上早些年的问题:

  1. QQ等程序聊天,双方是否使用SOCKET通信?应该不会都是通过服务器吧,那样服务器负担得多大啊?
  2. 如果是SOCKET,那么多的好友,一下子得建立多少个啊?还得考虑上线下线隐身等乱七八糟的问题。
  3. 请高手帮忙指点一下这种复杂程序的结构,谢谢。

  我还是很有发言权的呀,我毕业设计就是写的这个(不过当时用的是vc写的,带文件传输的)@hl_ghost
  我来说下我的思路吧:
1.如何知道谁在线?
      Server维护一个list就ok了(存所有人的ip,名字,在线等)
2.如何让服务器随时能找到你?
   前提:内网机器如果不主动向外发起连接,外网机没法直连内网的,这也是内网机安全的原因之一吧,又因为路由器会把这个关系记录下来,但是过一段时间这个记录可能会丢失 ,所有每一个客户端    每隔一定时间就会向服务器发送消息,以保证服务器可以随时找到你,这东西被称为心跳包。
3.如何跨内网直连
   Nat打洞(难):
   我简单说下原理,有两个客户端A,B ,当然必须有Server啦(他可以随时连接A,B)
   当A想连B时,A就回从Server那要B的ip,然后与B建立连接(第一次不能成功的,因为看红字)。
   这时A告诉Server,我找不到B,你替我告诉他一声,我想与它连接,服务器就告诉B,你给A下一个请帖(B发请求向A)! 
   这时A再向B发起连接就可以成功了(以后就不用server帮忙了)。
4.如何保证数据的可靠性(难)
   滑动窗口协议,这个一句话两句说不清楚啦,自己google下。
5是否在线。
     我的设计是每隔40秒客户端把Server中存自己的信息中的在线改为真,而服务器每过45秒就检查这个在线变量是否为真,真的话把他改成假,如果假的话就说明这个人在45秒没有向Server报到=>他网络出现异常了,掉线了,向其它人发这个人的掉线通知。(这么设计原因在于当用户网断了没有发下线通知,我们也能知道他不在线了)
6文件传输(难)
   把文件读到buf里,然后每次发1024b(当收到接收方确认后再发下一个1024b)。

参考文章

  http://www.cppblog.com/tx7do/archive/2009/11/09/100513.html

  http://bbs.csdn.net/topics/270063434

转载于:https://www.cnblogs.com/lcw/p/3565459.html

【Socket】关于socket长连接的心跳包相关推荐

  1. 关于socket长连接的心跳包

    出于最近对im研究的兴趣,看到smack里有个30s发送一个空消息的线程,了解了下关于心跳包,keepalive的知识. TCP的socket本身就是长连接的,那么为什么还要心跳包呢? 搜索到的资料解 ...

  2. php 长连接 心跳包,Swoole中的长连接和心跳包

    长连接说简单一点就是不会断的连接 

  3. 长连接与心跳包 Persistent connection and HearBeats

    http://stackoverflow.com/questions/1480236/does-a-tcp-socket-connection-have-a-keep-alive http://sta ...

  4. java nio socket长连接_nio实现Socket长连接和心跳

    前段时间用bio方式,也就是传统io实现了socket的长连接和心跳,总觉着服务端开启多线程管理socket连接的方式过于消耗资源,数据并发的情况下可能会影响到性能,因此就尝试使用nio改进原来的代码 ...

  5. Socket Client 长连接及心跳检测

    简介: 所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象.一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制.从所处的地位来讲,套接 ...

  6. 聊聊 TCP 长连接和心跳那些事

    1 前言 可能很多 Java 程序员对 TCP 的理解只有一个三次握手,四次挥手的认识,我觉得这样的原因主要在于 TCP 协议本身稍微有点抽象(相比较于应用层的 HTTP 协议):其次,非框架开发者不 ...

  7. TCP长连接,心跳机制介绍

    TCP长连接,心跳机制介绍 长连接 为何要长连接 心跳 心跳为何设置在服务器端 心跳维持长连接 TCP keep-alive的三个参数 参数的具体意义 心跳的使用场景 长连接 TCP经过三次握手建立连 ...

  8. 长连接、心跳和断线重连

    长连接.心跳和断线重连 2017年06月22日 18:38:53 天涯遍地是小草 阅读数 7938 一.概述 目前IM软件有一个基本的功能就是长在线,即只要有网络就保持登录,然而,网络状态是无法预测的 ...

  9. JAVA网络编程Socket常见问题 【长连接专题】

    一. 网络程序运行过程中的常见异常及处理 第1个异常是 java.net.BindException:Address already in use: JVM_Bind. 该异常发生在服务器端进行new ...

最新文章

  1. https安全传输揭秘
  2. jinja2 {{}} href 双大括号
  3. 修改远程桌面端口_花生壳(内网穿透)服务做远程桌面登录
  4. AUTOSAR从入门到精通100讲(二十二)-AUTOSAR通信篇—CANTP模块
  5. date 显示或设置系统时间和日期
  6. Android开发环境准备和常用命令总结
  7. How Many Pieces of Land ? (UVA-10213)
  8. EXCEL批量删除当前目录下所有工作薄的所有工作表的指定行
  9. 年会季来临,年会会场管理一招搞定!
  10. 黑马程序员_面向对象的三大特征
  11. linux虚拟机镜像下载
  12. stm32定时器4重映射
  13. 开源软件的许可证(License)
  14. 网络攻击机制和技术发展综述
  15. 编译程序原理VS解释程序原理
  16. EXCEL数据分析项目 - 商贸企业销售数据分析实战
  17. Vray和PS的冬景效果图制作教程蓝海创意云渲染
  18. DAMO-YOLO全流程代码解读
  19. 基金股市理财经验分享(个人体会)
  20. 图论学习笔记——一笔画(最少笔画)问题

热门文章

  1. python字典值求和_Python两个字典键同值相加的方法总结
  2. Linux笔记-Centos7.6安装Qt5.5.1
  3. Redis工作笔记-spring-data-redis的基本使用
  4. matlab for循环不覆盖,Matlab for 多个变量循环能不能这样啊 ,求教高手!!!!...
  5. java dump分析工具_Java虚拟机详解(七)------虚拟机监控和分析工具(1)
  6. 年龄到底怎么算才对_如意甘霖vs嘉和保,到底谁才是最佳男性重疾险
  7. php 执行多个文件,PHP提高执行多个查询时读取一千行文件的性能
  8. 题目1003:A+B
  9. (王道408考研操作系统)第四章文件管理-第二节4:磁盘的管理
  10. [Python]网络爬虫(12):爬虫框架Scrapy的第一个爬虫示例入门教程