Java 服务端 socket 掉线重启后,客户端自动重连
目的
强调:setSoTimeout()函数的重要性,目的是为了写出更健壮的程序。
问题:如果客户端发起的socket 在连接后,读取数据流之前,刚好服务器端突然断线了,紧接着又重启了,则当前socket连接,容易死锁,从而整个客户端程序停滞。
一般网上的思路,都是要判断服务端的状态、发送心跳包什么之类的,我个人认为这些操作比较繁琐、也不一定有效,经过多番摸索,终于明白了函数socket.setSoTimeout() 的重要性:
方法
1)使用socket 短连接
2) 启用 socket 的 setSoTimeout()的方法,以及ConnectTimeout() 连接超时。
3)捕捉异常:java.net.SocketTimeoutException: Read timed out后,重新开启一个socket。
具体代码如下:
try {// 并将其连接到指定主机上的指定端口号while (true) { // Java里Socket的循环往复使用 https://www.pianshen.com/article/58251192706/socket = new Socket(); //使用socket 短连接socketAddress = new InetSocketAddress(ip, port);//socket.setKeepAlive(true);socket.connect(socketAddress, 2*1000);//设置超时为20秒socket.setSoTimeout(3*1000);//设置读操作超时时间 3 s,//这样才能捕捉异常:java.net.SocketTimeoutException: Read timed out,非常重要,否则//当在连接伤后,刚好服务器器socket server断开,则直接运行下面语句中的readLine()会死锁out = new PrintStream(socket.getOutputStream());out.println("push message...");// 向服务器端发送数据// 读取服务器端数据br = new BufferedReader(new InputStreamReader(socket.getInputStream()));ret = br.readLine();releaseResource(br ,out, socket);if( ret == null ){break;}Thread.sleep(1 * 1000);}} catch (Exception e) {System.out.println("--- socket连接error-----------");e.printStackTrace();} finally {releaseResource(br ,out, socket);try {Thread.sleep(3 * 1000); //必须要 等待一定的秒数,等远端的socket server在足够时间内,启动起来,再尝试重连。} catch (Exception e) {}System.out.println("- - - finally语句中,socket server断开后,开始重连-----------\n\n");}}
上面代码,如果刚好在执行br = new BufferedReader(n。。。之后,执行语句ret = br.readLine() 之前,刚好服务端的socket service断掉、并瞬间快速重启了,那么之前的建立的socket TCP/IP就其实是个死的TCP/IP连接,这个时候执行 readLine()语句就会timeout死锁,程序停滞,如果前面没有设置setSoTimeout(),那么这个异常就不会被捕捉到,从而一直停在语句readLine()那里死锁下去。那这个不是我们期望的,当前socket连接发送来的数据,丢失了也就算了;后续的要能正确接受、保存。
如果前面设置了socket.setSoTimeout(3*1000),就会在3秒内,捕捉到这个异常,从而放弃这个socket,进入重连。重连后,由于通道中会继续存在先前死的TCP/IP连接,可能会再次报告SocketTimeoutException异常,但是不要急(欲速则不达),经过几次反复重连后,服务器系统会重新开辟一个新的TCP/IP连接,回收老的、有问题的TCP/IP连接,整个重连就彻底变正常了。
---------------------------------
参考: java.net.SocketTimeoutException: Read timed out报警_summer089089的博客-CSDN博客
connect timeout 是建立连接的超时时间;
read timeout, 是传递数据的超时时间。
ConnectTimeout只有在网络正常的情况下才有效,而当网络不正常时,ReadTimeout才真正的起作用,即IdIOHandlerStack 里的 WaitFor 是受ReadTimeout限制的,因此,这2个属性应该结合实用。
Java 服务端 socket 掉线重启后,客户端自动重连相关推荐
- 图解Java服务端Socket建立原理
1.前言 1.1 目标 本文通过一个典型的java server socket代码,逐层剖析其tcp协议的服务端建立的原理,其中会涉及到linux内核的实现,本文会以简单通俗的图形将其中原理展示给大家 ...
- 吃透阿里P8推荐424页Java服务端研发知识图谱后,直接入职蚂蚁P6
前言 蓦然回首自己做开发已经十年了,这十年中我获得了很多,技术能力.培训.出国.大公司的经历,还有很多很好的朋友.但再仔细一想,这十年中我至少浪费了五年时间,这五年可以足够让自己成长为一个优秀的程序员 ...
- java服务端限流框架,美团大众点评服务框架Pigeon
服务框架Pigeon架构 ? Pigeon提供jar包接入 ,线上运行在tomcat里 ? Monitor-CAT ,负责调用链路分析.异常监控告警等 ? 配置中心-Lion ,负责一些开关配置读取 ...
- 基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互
基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互 一.前言 1.Java服务端程序代码的项目名为TcpSocketServerOfJava,包名为com.exam ...
- 【学习笔记】在windows下进行基于TCP的本地客户端和服务端socket通信
文章目录 socket介绍 java中使用socket 基于tcp的socket通信 使用ServerSocket类创建一个web服务器:(java) windows下的基于tcp的socket编程( ...
- 服务器关闭重启后客户端socket能自动连接吗_用Python 撸一个 Web 服务器
从一个 Hello World 程序说起 要编写 Web 服务器,需要用到一个 Python 内置库 socket.Socket 是一个比较抽象的概念,中文叫套接字,它代表一个网络连接.两台计算机之间 ...
- java comet_用java实现comet,基于 HTTP长连接的实现,用于从服务端实时发送信息到客户端...
http://homelink.javaeye.com/blog/293328#comments 参考文档 http://www.ibm.com/developerworks/cn/web/wa-lo ...
- QtJava笔记-Qt与Java进行SSL双向认证(Qt客户端,Java服务端)
这里使用Java作为服务端,使用Qt作为客户端. 程序运行截图如下: 这里的证书Qt使用的p12,Java使用的jks,看以前的博文生成. 源码打包下载地址: https://github.com/f ...
- C++客户端和java服务端互相加解密
这段时间在公司做一个APP和移动网关通信加密的项目,本来是想采用https或者openssl来加密通道,但考虑到数据本身的安全性问题,还是打算自己编写加解密算法. 一.流程 1.客户端生成AES密钥和 ...
最新文章
- 秒懂词向量Word2vec的本质
- java逻辑移位和算术移位,关于对移位运算的理解
- USB鼠标失灵的解决办法
- HTML--三种样式插入方法--链接---表格---列表
- 《飞机大战》安卓游戏开发源码(三)
- NGINX进程的基本操作和基础知识
- 骚操作,简单修改源码,让你的postman自动生成POJO代码
- C++中cout流的输出顺序
- js格式化xml并高亮显示关键字
- Spring Boot入门篇-@RequestParam/@RequestBody配置
- arduino代码_Arduino超声波传感器测距代码完全解析
- 树莓派开发—语音识别功能
- BLE蓝牙应用生成Android/iOS APP以及小程序
- 802.11 - NDP反馈报告
- visibility:属性
- 3.SpringBoot整合Mybatis(一对多)
- EF更新使用AutoMapper_se7en3_新浪博客
- 中国象棋中的跳马问题
- Windows 环境下查看 Redis 版本号命令
- 校园企业车辆维修报修管理系统设计与开发