当前位置:首页 > 开发 > 编程语言 > 网络编程 > 正文

socket.sendUrgentData在windows7下出现17次失效的问题

发表于: 2013-02-21   作者:coral0212   来源:转载   浏览次数:
摘要: 以下是转载内容,转载地址是: http://chenke1215.blog.163.com/blog/static/124414520103611222617/   http://chenke1215.blog.163.com/blog/static/124414520103611222617/ 写道 最近在开发中遇到一个问题,就是如何判断远端服务器是否已经断开连接,如果断开那

以下是转载内容,转载地址是:

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();
}

 这里非常肯定的是: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.sendUrgentData在windows7下出现17次失效的问题

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
目前开发的系统里很多控件样式和动画比较复杂,应该是之前同事用Blend做的,这种神器不用太浪费了,
在windows7操作系统上安装SQL SERVER 2005,默认情况下总要提示 IIS功能要求警告,这是因为SQL2005
错误一 解决:启动“Net.Tcp Port Sharing Service”服务。 错误二 解决: 一、使用命令“WHOAMI /U
今天遇到的问题是: 在ie7下面出现这样的情况,自己元素(本意是z-index较高,上层)被盖住了,处在
window.close(),一看就知道是用来关闭浏览器窗口的方法。W3CSchool对该方法的解释如下:方法 clo
最新发现一个BUG,翻页在IE8下好好的;在IE6下出问题(点击页面不动,但是页面却记住了页码的标识)
1) 创建快捷方式文件 gedit ~/.local/share/applications/eclipse.desktop 2) 增加文件内容如下: [
问题: 在项目开发中遇到了一个spring事务失效的问题,检查配置文档,都没有问题,其他的类中的方法
在Linux中经常通过ifconfig 命令设置IP地址,但每次设置完成后,重启服务器后IP地址就会清空。具体
问题: 在项目开发中遇到了一个spring事务失效的问题,检查配置文档,都没有问题,其他的类中的方法
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号