日期:2014-05-20  浏览次数:20616 次

网络何时失效(完美解决追加200分)---socket的另一方关闭或者异常断开程序该如何知道
一个用java编写的网络服务程序,服务了多个客户端,意即与多个目标成功建立了socket连接,并且已经互相交互了一些数据,出于某些原因,服务程序不能主动关闭这个socket.但是当客户端关闭了,或者异常断开了,这个服务程序该如何知道.
  有三个问题值得提一下:
  首先,我使用的是1.4的new   io来做,使用了非阻塞模式,在单个线程中处理这些服务,因此,不能通过阻塞在Socket.read方法,当抛出异常时将其断开;
  其次,使用Socket.sendUrgentData方法,发送紧急数据报的方法不可行;
  再者,不能发送测试数据来测试连接是否有效,因为客户端不是我写的,无法识别测试数据.
  
  这个问题我想了好久了,也试过了N种方法,网络上搜索的办法都在上面三条中被排除,不能用.
  如果完美解决这个问题,视可行性,我额外加分,300封顶
  一时仓促,可能问题表达不是很清晰,有兴趣的可加我QQ:124340767

------解决方案--------------------
帮我群里兄弟顶个!
------解决方案--------------------
服务器端要求客户端定时发送空数据包过来,如果没收到相应客户端的数据包!关闭socket!
还可以在服务器端直接多每个socket进行连接超时设置,详细见JDK API 说明Socket部分!
------解决方案--------------------
考虑用其他通信模型,例如各平台均支持的SELECT。如果你不用它并使用非阻塞就不能单单以READ返回0来判断是否断线,如果能与客户端保持协议就最好,但因为你客户端不是自己写的所以没办法,有一个方法不知道可行不,在服务器端记录每个SOCKET的数据收发时间,开一个线程检查每个SOCKET的时间是否超过一定范围的时间,如果是则CLOSE并移除记录。
------解决方案--------------------
楼主跟我的问题正好相反,我这边是客户端从服务器端收数据,服务器端好像只管不停的发。没有心跳协议,也没有其它的协议,就是那边只管发,这边只管收。

突然路由器断了,可是它好像还不知道。我再登录,它不让我登录(好像限制了一个IP只能有一个连接),但是它又规定在我若干秒内必须登录成功。郁闷中,不知道有无什么解决方法?
------解决方案--------------------
这是个老问题了,算个经典的问题吧。

----------------------------------------------------
不能通过阻塞在Socket.read方法,当抛出异常时将其断开!
----------------------------------------------------

为什么不能,不要以为NEW I/O读取一个关闭了的Socket时不会抛出异常,而是什么也读不到。
你这样解理是错误的。新IO一样会抛出异常。


“服务器永远也不会关闭连接,它等待客户端中断Socket。当Socket中断时,会抛出一个异常。”

这是《java网络编程》第三版399页一个句话,详见第十二章 非阻塞I/O 中ChargenServer.java。