以下是转载内容,转载地址是:
http://chenke1215.blog.163.com/blog/static/124414520103611222617/
http://chenke1215.blog.163.com/blog/static/124414520103611222617/ 写道
最近在开发中遇到一个问题,就是如何判断远端服务器是否已经断开连接,如果断开那么需要重新连接。
首先想到socket类的方法isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,但经过试验并查看相关文档,这些方法都是本地端的状态,无法判断远端是否已经断开连接。
然后想到是否可以通过OutputStream发送一段测试数据,如果发送失败就表示远端已经断开连接,类似ping,但是这样会影响到正常的输出数据,远端无法把正常数据和测试数据分开。
最后又回到socket类,发现有一个方法sendUrgentData,查看文档后得知它会往输出流发送一个字节的数据,只要对方Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节,而SO_OOBINLINE属性默认情况下就是关闭的,太好了,正是我需要的!
于是,下面一段代码就可以判断远端是否断开了连接:
try{
socket.sendUrgentData(0xFF);
}catch(Exception ex){
reconnect();
}
首先想到socket类的方法isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,但经过试验并查看相关文档,这些方法都是本地端的状态,无法判断远端是否已经断开连接。
然后想到是否可以通过OutputStream发送一段测试数据,如果发送失败就表示远端已经断开连接,类似ping,但是这样会影响到正常的输出数据,远端无法把正常数据和测试数据分开。
最后又回到socket类,发现有一个方法sendUrgentData,查看文档后得知它会往输出流发送一个字节的数据,只要对方Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节,而SO_OOBINLINE属性默认情况下就是关闭的,太好了,正是我需要的!
于是,下面一段代码就可以判断远端是否断开了连接:
try{
socket.sendUrgentData(0xFF);
}catch(Exception ex){
reconnect();
}
这里非常肯定的是:SO_OOBINLINE默认是关闭的,也就是说,sendUrgentData发送的字节,在客户端(准确的说是接收端,有时服务器端也接收消息)是舍弃的,但是这种情况在win7系统下会出现异常情况,即发送端在执行17次sendUrgentData后,发生异常,异常的结果是:
http://d2100.com/questions/16360 写道
我目前正在调试交换数据通过 TCP 连接的两个 Java 应用程序。
一个应用程序中,TCP 客户端,定期通过调用Socket#sendUrgentData(int)其他,TCP 服务器,发送紧急数据。18 尝试发送紧急数据,TCP 客户端将引发了以下异常
java.io.IOException:BrokenPipe
at java.net.PlainSocketImpl.socketSendUrgentData(Native Method)
at java.net.PlainSocketImpl.sendUrgentData(PlainSocketImpl.java:541)
at java.net.Socket.sendUrgentData(Socket.java:927)TCP 服务器会引发此异常
java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)我相信例外情况引起试图关闭连接、 插座来读写。不明白的是为什么连接或插座成为封闭后调用 sendUrgentData() 17 次。我能重复一遍,而且它的发生总是后 17 倍。
如果我在 Windows 上运行的客户端和服务器,出现问题。如果我的客户端和服务器上运行 Solaris 问题不会发生。如果我在 Windows 上 Solaris 和服务器上运行客户端时出现问题。如果在 Solaris 上运行在 Windows 客户端和服务器,则不出现问题。这让我想起了它可能相关的 Windows 吗?
使用 Wireshark 在该连接上看到以下交通
--> = from TCP client to TCP server
<-- = from TCP server to TCP client
--> [PSH, ACK, URG] (Seq=1, Ack=1)
<-- [ACK] (Seq=1, Ack=2)
--> [PSH, ACK, URG] (Seq=2, Ack=1)
<-- [ACK] (Seq=1, Ack=3)
...
--> [PSH, ACK, URG] (Seq=17, Ack=1)
<-- [RST, ACK] (Seq=1, Ack=18)
本人测试的结果是:
java.net.SocketException: Software caused connection abort: recv failed at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at java.io.DataInputStream.read(DataInputStream.java:83) at cn.DstClient.main(DstClient.java:25)
这里需要声明的一点是,在xp下是没有任何问题的,也就是说sendUrgentData在win7下使用,要自己处理一下.以下是外文翻译的结果,大家凑合着看看,
写道
我猜你其实正确正在接受紧急数据失败的应用程序中的数据,它将比你预期和吗?
有很多原因,此操作失败,特别是如果您在尝试它在跨平台的情况: 在 TCP 有两个相互矛盾描述如何紧急数据作品, RFC 793 TCP 说紧急指针指示如下紧急数据的字节的详细信息,但RFC 1122更正这以及国家紧急指针指示紧急数据的最后一个字节。这会导致互操作性问题,如果一个对等端使用 RFC 793 定义和其他使用 RFC 1122 定义。
因此,第一次确认您的应用程序实际上正在紧急数据的正确字节。是的我说字节,有更多的兼容性中的复杂性 Windows 仅支持的带数据的单个字节,而 RFC 1122 指定 TCP 必须支持任意长度的紧急数据字节序列。Windows 还没有指定如何,或者如果它将缓冲区随后的带数据,因此,如果您是慢读一个字节的紧急数据和紧急数据的另一个字节到达某个字节可能会丢失 ; 然后虽然我们的测试表明,Windows 不会缓冲紧急数据。这一切都使信号使用 TCP 窗口上的紧急数据有点不可靠的带外使用。
还有,如果你碰巧使用重叠的 I/O 来关于所有其他问题。
我已经介绍这一点更加深入,尽管从 c + + 的角度,在这里: http://www.serverframework.com/asynchronousevents/2011/10/out-of-band-data-and-overlapped-io.html
还有一点需要说明的是:flex中socket是没有SO_OOBINLINE属性设置的,所以呢,需要另外的办法来考虑了.
有的同学说new 一个DataInputStream即可,我想说的是,每次都去new,实在不为明智之举.
相关推荐
Socket.IO和Socket.IO-Client是两个非常重要的库,主要用于实现实时双向通信,尤其是在Web开发领域。它们使得JavaScript客户端(浏览器)与Node.js服务器之间能够建立WebSocket风格的连接,提供了强大的实时通信解决...
Socket.IO是一个流行的JavaScript库,它提供了跨平台、跨浏览器的实时应用框架,支持WebSocket以及其他多种降级方案,确保在各种网络条件下的通信稳定性。 首先,我们要理解Socket.IO的核心概念。WebSocket是一种在...
Socket.IO的目标是提供一个跨平台、跨浏览器的实时通信解决方案,通过透明地在各种传输协议之间切换,确保在任何情况下都能实现可靠的数据传输。 socket.io.js是Socket.IO库的核心JavaScript文件,它包含了Socket....
基于vue3+socket.io的聊天应用,比较完整,略好看 基于vue3+socket.io的聊天应用,比较完整,略好看 基于vue3+socket.io的聊天应用,比较完整,略好看 基于vue3+socket.io的聊天应用,比较完整,略好看 基于vue3...
基于 WebSocket 协议,Socket.IO 提供了更高级别的接口,能够处理各种网络条件下的连接问题,确保数据的可靠传输。在这个“基于socket.io聊天室功能”的项目中,我们将探讨如何使用 Socket.IO 构建一个简单的聊天室...
7. **安全性**:在使用Socket.IO进行实时通信时,必须注意安全问题,比如防止XSS攻击、CSRF攻击,以及确保数据传输的加密性。微信和支付宝小程序平台都有自己的安全机制,开发者需遵循其规则。 8. **性能优化**:...
因为项目中需要实现后端推荐消息到前端,经过研究和讨论,最终决定用Socket.io实现消息的推送,而在SpringBoot用Socket.io实现消息推送在网上的例子太少了,本人研究了一天的Socket.io,终于对Socket.io的应用比较...
Vue-Socket.io, vuejs的socket.io 实现 Vue-Socket.io Vuejs 2和Vuex的socket.io 实现安装npm install vue-socket.io --save用法配置从URL字符串自动连接import V
7. **错误处理**:在使用Socket.IO时,需要处理各种可能出现的错误,如网络错误、连接失败、消息发送失败等。通过错误监听器,你可以捕获这些错误并做出相应的响应。 8. **兼容性**:虽然Socket.IO主要设计用于Web...
cocoscreator下使用ts版本的socket.io,后端socket.io包版本是 ^2.2.0 需要使用1.4.4版本的socket.io.js,配合1.4.5版本的.d.ts声明文件实现智能提示, 使用方法: 在脚本开头引入js: import { connect } from "./...
Socket.IO 是一个实时应用框架,它为开发人员提供了一种简单的方式来实现在Web上进行双向通信,即服务器和客户端可以实时、双向地交换数据。在Java中创建一个Socket.IO客户端,你需要依赖一些特定的库来处理相关的...
这个库基于WebSocket协议,并且在WebSocket不支持或者不可靠的环境下提供了多种备选方案,如polling、long-polling等,确保了在各种网络环境下的稳定性和兼容性。以下是对Socket.IO.js的详细介绍: 1. WebSocket...
粘包和半包是网络通信中的常见问题,主要出现在TCP协议中。由于TCP为了提高传输效率,会将多个小的数据包合并成一个大的数据包进行发送(粘包),或者将一个大数据包分成多个小的数据包发送(半包)。这可能导致接收...
来源于网上的博文,我对源码做了一些增强,并把需要的node.js、socket.io、jQuery、服务端和客户端源码,全部打在一起(node.js的npm需要在线安装,聊天室样例也有引用到互联网上的js文件,我把它们全部都本地化了,...
session.socket.io, 在 socket.io 中,表示/连接会话 session.socket.io ( SessionSockets ) 这个小模块简化了 socket.io 使用express或者连接中间件的http会话的使用。 它没有依赖项,可以使用任何与表示或者连接...
uni.socket.io.js、针对手机端改的一个版本
Layaair Socket.io文件 Layaair Socket.io文件 文档https://blog.csdn.net/nicepainkiller/article/details/91043252 https://blog.csdn.net/nicepainkiller/article/details/91043252
Unity3d For Socket.IO 带 Authorization Unity3d For Socket.IO 带 Authorization 使用方式 https://blog.csdn.net/nicepainkiller/article/details/80805472 使用方式 ...
Socket.IO 是一个实时应用框架,它为开发人员提供了一种简单的方式来实现在Web上进行双向通信,即服务器和客户端之间的实时、低延迟的数据传输。在Java环境中,我们可以使用Socket.IO的Java客户端库来构建这样的应用...
《FlashSocket.IO-0.7.x.zip:Flex与Socket.IO通信的桥梁》 在现代Web开发中,实时性成为了一项重要的需求,特别是在构建交互性强的网页应用时。FlashSocket.IO-0.7.x.zip是一个专门针对这种情况设计的库,它为Flex...