【Socket】关于socket长连接的心跳包
TCP的socket本身就是长连接的,那么为什么还要心跳包呢?
在smack里有个30s发送一个空消息的线程,同样关于心跳包(keepalive)
据网络搜索到的资料解释如下
- 内网机器如果不主动向外发起连接,外网机没法直连内网的,这也是内网机安全的原因之一,又因为路由器会把这个关系记录下来,但是过一段时间这个记录可能会丢失 ,所有每一个客户端每隔一定时间就会向服务器发送消息,以保证服务器可以随时找到你,这东西被称为心跳包。
- 理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的数据清理,重新连接……当然,这个自然是要由逻辑层根据需求去做了。总的来说,心跳包主要也就是用于长连接的保活和断线处理。一般的应用下,判定时间在30-40秒比较不错。如果实在要求高,那就在6-9秒。
- 如果不主动关闭socket的话,系统不会自动关闭的,除非当前进程挂掉了,操作系统把占用的socket回收了才会关闭。为什么需要心跳连接主要是判断当前连接是否是有效的、可被使用的。在实际应用中假设一段时间没有数据传输时候理论上说应该连接是没有问题的,但是网络复杂,中途出现问题也是常见的,网线被掐断了、对方进程挂掉了、频繁丢包等,这时候TCP连接是不可使用的,但是对于应用层并不知道,如果需知道网络情况则要很复杂的超时进行了解,TCP从底层就实现了这样的功能。心跳机制是TCP在一段时间间隔后发送确认连接端是否还存在,如果存在的话就会回传一个包确定网络有效,如果心跳包有问题,则通知上层应用当前网络有问题了。
- 这取决于你的server端的超时配置, 每个socket连接都是长连接,它是一个相当占用系统资源的通信管道, 如果这个长连接什么事也没干硬是要占着资源,则server端可以选择关闭这个连接,以省下资源让更多的用户连接进来。
- 所以,即便客户端的是采用死循环while(true)方式连到服务端,对于特定的客户端和服务端类型来说也需要一定时间间隔的心跳(告诉服务端,我还活着,虽然我没干活也没说话,但别把我关了)
以前开发手机游戏时,索爱有一款手机有强制要求,客户端如果超过三分钟无消息发向网络服务端,则会在客户端自动地强制把socket关断。因为socket长连接相对于手机这样资源少的设备来说是宝贵的资源。 (这个强制是指客户端系统自动关的,不是我们代码close的)
- 在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE。系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。
- 心跳包一般来说都是在逻辑层发送空的echo包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。
- 其实,要判定掉线,只需要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上早些年的问题:
- QQ等程序聊天,双方是否使用SOCKET通信?应该不会都是通过服务器吧,那样服务器负担得多大啊?
- 如果是SOCKET,那么多的好友,一下子得建立多少个啊?还得考虑上线下线隐身等乱七八糟的问题。
- 请高手帮忙指点一下这种复杂程序的结构,谢谢。
我还是很有发言权的呀,我毕业设计就是写的这个(不过当时用的是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长连接的心跳包的更多相关文章
- 正确理解IM长连接的心跳及重连机制,并动手实现(有完整IM源码)
1.引言 说道“心跳”这个词大家都不陌生,当然不是指男女之间的心跳,而是和长连接相关的.顾名思义就是证明是否还活着的依据. 什么场景下需要心跳呢?目前我们接触到的大多是一些基于长连接的应用需要心跳来“ ...
- JAVA网络编程Socket常见问题 【长连接专题】
一. 网络程序运行过程中的常见异常及处理 第1个异常是 java.net.BindException:Address already in use: JVM_Bind. 该异常发生在服务器端进行new ...
- php socket如何实现长连接
长连接是什么? 朋友们应该都见过很多在线聊天工具和网页在线聊天的工具.学校内有一种熟悉的功能,如果有人回复你了,网站会马上出现提示,此时你并没有刷新页面:Gmail也有此功能,如果邮箱里收到了新的邮件 ...
- Socket服务端口长连接最多能支持多少?
答案是无限的.视服务端的资源而不同. 以前一直认为服务端在Accept客户端连接后,会开启一个新的端口与客户端建立链路,但这是错误的.事实上,一个连路是由Server IP+server Port + ...
- 基于netty实现的长连接,心跳机制及重连机制
技术:maven3.0.5 + netty4.1.33 + jdk1.8 概述 Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速 ...
- JAVA实现长连接(含心跳检测)Demo
实现原理: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的. 如果,长时间未发送维持连接包,服务端程序将断开连接. 客户端: Client通过持有Sock ...
- 嵌入式开发之网络心跳包---阻塞和非阻塞以及是否有必要心跳包heartbeat
1.1 TCP和UDP的心跳包是用来维持长连接的 心跳包只是用来检测socket的链接状态 2.1 非阻塞情况下TCP 心跳包是否有必要建立心跳包 需要, a.如果说 严格 检测掉线的话 那么不管是不 ...
- iOS swift项目IM实现,从长连接到数据流解析分析之Socket
iOS swift项目IM实现,从长连接到底层数据解析分析之Socket 一:项目简介: 去年开始接手了一个国企移动项目,项目的需求是实现IM即时通讯功能. * 一期版本功能包括了: ...
- Socket的长连接和短连接
讨论Socket必讨论长连接和短连接 一.长连接和短连接的概念 1.长连接与短连接的概念:前者是整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接:后者是每次请求,都新建 ...
随机推荐
- pandas学习(创建多层索引、数据重塑与轴向旋转)
pandas学习(创建多层索引.数据重塑与轴向旋转) 目录 创建多层索引 数据重塑与轴向旋转 创建多层索引 隐式构造 Series 最常见的方法是给DataFrame构造函数的index参数传递两个或 ...
- metasploit常用服务扫描和利用模块
metasploit常用服务扫描和利用模块 SMB扫描 smb枚举auxiliary/scanner/smb/smb_enumusers 扫描命名管道auxiliary/scanner/smb/pip ...
- 机器学习 支持向量机(SVM) 从理论到放弃,从代码到理解
基本概念 支持向量机(support vector machines,SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器.支持向量机还包括核技巧,这使它成为实质上的非线性分 ...
- 基于tensorflow搭建一个神经网络
一,tensorflow的简介 Tensorflow是一个采用数据流图,用于数值计算的 开源软件库.节点在图中表示数字操作,图中的线 则表示在节点间相互联系的多维数据数组,即张量 它灵活的架构让你可以 ...
- Python字典中的值为列表或字典的构造方法
转自: https://blog.csdn.net/buside/article/details/81323871 1.值为列表的构造方法 dic = {} dic.setdefault(key,[] ...
- eclipse如何更改webroot
在项目上右击-->点击属性-->点击web project Setting
- 如何实现跨域获取iframe子页面动态的url
有的时候iframe的子页面会动态的切换页面,我们在父页面通过iframe1.contentWindow.window.location只能获取同源的子页面的信息.获取跨域的子页面信息会报错. 这时可 ...
- javascript中break与continue,及return的区别
a).在循环体中, break是跳出整个循环,不执行以后的循环语句: continue是结束本次循环语句,进入下一个循环: b). 在if判断句,结束该函数的执行时,用 return: c). 在函数 ...
- 来自极客头条的 15个常用的javaScript正则表达式
摘要收集整理了15个常用的javaScript正则表达式,其中包括用户名.密码强度.整数.数字.电子邮件地址(Email).手机号码.身份证号.URL地址. IPv4地址. 十六进制颜色. 日期. Q ...
- JSON数据之使用Fastjson进行解析(一)
据说FastJson是目前最快的解析Json数据的库,而且是国人开发出来的开源库.顶一下,付上官方网址:http://code.alibabatech.com/wiki/pages/viewpage. ...