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)
{
}
}
}
}

  另外记一个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

【Socket】关于socket长连接的心跳包的更多相关文章

  1. 正确理解IM长连接的心跳及重连机制,并动手实现(有完整IM源码)

    1.引言 说道“心跳”这个词大家都不陌生,当然不是指男女之间的心跳,而是和长连接相关的.顾名思义就是证明是否还活着的依据. 什么场景下需要心跳呢?目前我们接触到的大多是一些基于长连接的应用需要心跳来“ ...

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

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

  3. php socket如何实现长连接

    长连接是什么? 朋友们应该都见过很多在线聊天工具和网页在线聊天的工具.学校内有一种熟悉的功能,如果有人回复你了,网站会马上出现提示,此时你并没有刷新页面:Gmail也有此功能,如果邮箱里收到了新的邮件 ...

  4. Socket服务端口长连接最多能支持多少?

    答案是无限的.视服务端的资源而不同. 以前一直认为服务端在Accept客户端连接后,会开启一个新的端口与客户端建立链路,但这是错误的.事实上,一个连路是由Server IP+server Port + ...

  5. 基于netty实现的长连接,心跳机制及重连机制

    技术:maven3.0.5 + netty4.1.33 + jdk1.8   概述 Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速 ...

  6. JAVA实现长连接(含心跳检测)Demo

    实现原理: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的.       如果,长时间未发送维持连接包,服务端程序将断开连接. 客户端:       Client通过持有Sock ...

  7. 嵌入式开发之网络心跳包---阻塞和非阻塞以及是否有必要心跳包heartbeat

    1.1 TCP和UDP的心跳包是用来维持长连接的 心跳包只是用来检测socket的链接状态 2.1 非阻塞情况下TCP 心跳包是否有必要建立心跳包 需要, a.如果说 严格 检测掉线的话 那么不管是不 ...

  8. iOS swift项目IM实现,从长连接到数据流解析分析之Socket

    iOS  swift项目IM实现,从长连接到底层数据解析分析之Socket 一:项目简介:  去年开始接手了一个国企移动项目,项目的需求是实现IM即时通讯功能. * 一期版本功能包括了:       ...

  9. Socket的长连接和短连接

    讨论Socket必讨论长连接和短连接 一.长连接和短连接的概念 1.长连接与短连接的概念:前者是整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接:后者是每次请求,都新建 ...

随机推荐

  1. jquery $与jQuery

    jquery的兼容 ie8 <script type="text/javascript" src="<%=path%>/js/jquery-3.1.1. ...

  2. drupal笔记

    $app_root :网站根目录 安装 汉化:1将汉化包放置drupal8\sites\default\files\translations下安装:2极简版的话需要在extend(扩展)中安装Inte ...

  3. 爬虫之urllib.request基础使用(一)

    urllib模块 urllib模块简介: urllib提供了一系列用于操作URL的功能.包含urllib.request,urllib.error,urllib.parse,urllib.robotp ...

  4. AeroSpike踩坑手记1:Architecture of a Real Time Operational DBMS论文导读

    又开了一个新的坑,笔者工作之后维护着一个 NoSQL 数据库.而笔者维护的数据库正是基于社区版本的 Aerospike打造而来.所以这个踩坑系列的文章属于工作总结型的内容,会将使用开发 Aerospi ...

  5. jquery 简单的别踩白块小游戏

    写写简单的东西,效果如图: 1.html代码 <div class="warp"> <div class="title"> <h3 ...

  6. Servlet与HTTP介绍学习

    http介绍:http是一套规范,一种网络数据交互的标准协议,不同的语言,不同的数据想要实现合理的数据交互(例如:浏览器和服务器数据交互),就得按照他所规定的协议来,这样就会形成标准的(大家都认识的) ...

  7. 第01章 准备工作.md

    第1章 准备工作 1.1 本书的内容 本书讲的是利用Python进行数据控制.处理.整理.分析等方面的具体细节和基本要点.我的目标是介绍Python编程和用于数据处理的库和工具环境,掌握这些,可以让你 ...

  8. PushBackInputStream回退流

    [例子1] import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.PushbackInputS ...

  9. grpc 使用流程、使用技巧

    1.通过maven插件编译出java stub类. 2.对于批量调用的场景,我们可以使用FutureStub,对于普通的业务类型RPC,我们应该使用BlockingStub. 3.创建批量生成多个语言 ...

  10. 洛谷P1525 关押罪犯

    To 洛谷.1525 关押罪犯 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用 ...