最近在做项目的时候,遇到这样一个问题,如何判断 Socket 远程端连接是否关闭,如果关闭的话,就要重建连接Socket的类提供了一些已经封装好的方法, 如  isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,在测试时发现,这些方法都是本地端的状态,无法判断远端是否已经断开连接。

  其实在socket类中有一个方法sendUrgentData,它会往输出流发送一个字节的数据,只要对方Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节(在Java 中是抛出异常),而SO_OOBINLINE属性默认情况下就是关闭的。

  以下是示例代码仅供参考:

  1. public class Nksocket extends Thread{
  2. public String ip=null;//连接服务器的IP
  3. public Integer port=null;//连接服务器的端口
  4. private Socket socket=null;//套节字对象
  5. private boolean close = false; // 关闭连接标志位,true表示关闭,false表示连接
  6. private Integer sotimeout=1*1*10;//超时时间,以毫秒为单位
  7. //------------------------------------------------------------------------------
  8. public Nksocket(){
  9. init();
  10. }
  11. public Nksocket(String ip,Integer port){
  12. setIp(ip);
  13. setPort(port);
  14. init();
  15. }
  16. /**
  17. * 初始化socket对象
  18. */
  19. public void init(){
  20. try {
  21. InetAddress address = InetAddress.getByName(getIp());
  22. socket = new Socket(address,getPort());
  23. socket.setKeepAlive(true);//开启保持活动状态的套接字
  24. socket.setSoTimeout(sotimeout);//设置超时时间
  25. close=!Send(socket,"2");//发送初始数据,发送成功则表示已经连接上,发送失败表示已经断开
  26. }catch(UnknownHostException e) {
  27. e.printStackTrace();
  28. }catch(IOException e){
  29. e.printStackTrace();
  30. }
  31. }
  32. /**
  33. * 读数据线程
  34. */
  35. public void run() {
  36. while(true){
  37. //---------读数据---------------------------
  38. close = isServerClose(socket);//判断是否断开
  39. if(!close){//没有断开,开始读数据
  40. String readtext = ReadText(socket);
  41. if(readtext!=null && readtext.trim().length()>0){
  42. System.out.println("读取数据:"+readtext);
  43. }
  44. }
  45. //---------创建连接-------------------------
  46. while(close){//已经断开,重新建立连接
  47. try{
  48. System.out.println("重新建立连接:"+getIp()+":"+getPort());
  49. InetAddress address = InetAddress.getByName(getIp());
  50. socket = new Socket(address,getPort());
  51. socket.setKeepAlive(true);
  52. socket.setSoTimeout(sotimeout);
  53. close = !Send(socket,"2");
  54. System.out.println("建立连接成功:"+getIp()+":"+getPort());
  55. }catch(Exception se){
  56. System.out.println("创建连接失败:"+getIp()+":"+getPort());
  57. close=true;
  58. }
  59. }
  60. }
  61. }
  62. /**
  63. * 发送数据,发送失败返回false,发送成功返回true
  64. * @param csocket
  65. * @param message
  66. * @return
  67. */
  68. public Boolean Send(Socket csocket,String message){
  69. try{
  70. PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
  71. out.println(message);
  72. return true;
  73. }catch(Exception se){
  74. se.printStackTrace();
  75. return false;
  76. }
  77. }
  78. /**
  79. * 读取数据,返回字符串类型
  80. * @param csocket
  81. * @return
  82. */
  83. public String ReadText(Socket csocket){
  84. try{
  85. csocket.setSoTimeout(sotimeout);
  86. InputStream input = csocket.getInputStream();
  87. BufferedReader in = new BufferedReader(new InputStreamReader(input));
  88. char[] sn = new char[1000];
  89. in.read(sn);
  90. String sc = new String(sn);
  91. return sc;
  92. }catch(IOException se){
  93. return null;
  94. }
  95. }
  96. /**
  97. * 判断是否断开连接,断开返回true,没有返回false
  98. * @param socket
  99. * @return
  100. */
  101. public Boolean isServerClose(Socket socket){
  102. try{
  103. socket.sendUrgentData(0xFF);//发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
  104. return false;
  105. }catch(Exception se){
  106. return true;
  107. }
  108. }
  109. /**
  110. * 测试
  111. * @param ags
  112. */
  113. public static void main(String[] ags){
  114. Nksocket nksocket = new Nksocket("127.0.0.1",8090);
  115. nksocket.start();
  116. }
  117. //------------------------------------------------------------------------------
  118. public String getIp() {
  119. return ip;
  120. }
  121. public void setIp(String ip) {
  122. this.ip = ip;
  123. }
  124. public Integer getPort() {
  125. return port;
  126. }
  127. public void setPort(Integer port) {
  128. this.port = port;
  129. }
  130. }

  

参考资料:

http://blog.csdn.net/xyz_lmn/article/details/6146749

http://ivan4126.blog.163.com/blog/static/20949109220135284278806/

JAVA 判断Socket 远程端是否断开连接的更多相关文章

  1. 在HTTP通讯过程中,是客户端还是服务端主动断开连接?

    比如说:IE访问IIS,获取文件,肯定是要建立一个连接,这个连接在完成通讯后,是客户端Close了连接,还是服务端Close了连接.我用程序测模拟IE和IIS,都没有收到断开连接的消息,也就是都没有触 ...

  2. Java中使用Socket连接判断Inputstream结束,java tcp socket服务端,python tcp socket客户端

    最近在试着用java写一个socket的服务器,用python写一个socket的客户端来完成二者之间的通信,但是发现存在一个问题,服务器方面就卡在读取inputsream的地方不动了,导致后面的代码 ...

  3. 判断网络远端服务器是否断开连接(心跳连接:socket.sendUrgentData)

    1.socket类的方法isClosed().isConnected().isInputStreamShutdown().isOutputStreamShutdown()等,这些方法都是本地端的状态, ...

  4. java判断是移动端还是pc端

    // \b 是单词边界(连着的两个(字母字符 与 非字母字符) 之间的逻辑上的间隔), // 字符串在编译时会被转码一次,所以是 "\\b" // \B 是单词内部逻辑间隔(连着的 ...

  5. JAVA ANDROID SOCKET通信检测(SERVER)连接是否断开

    Pre 解决思路 代码后记: 客户端app上的部分代码 调用: 服务器上: 客户端判断服务器是否还活着代码: PRE 在利用socket写通讯程序的时候,想检测服务器是否还活着. 从网上找了很多资料, ...

  6. java socket 判断Socket连接失效

    要判断socket连接链路是否可用时,不能通过socket.isClosed() 和 socket.isConnected() 方法判断,要通过心跳包 socket.sendUrgentData(0x ...

  7. C#socket通信时,怎样判断socket双方是否断开连接

    我在Server端new了一个socket,然后bind,开了一个线程来accept前来连接的client,每接到一个client前来连接就新开一个线程和它进行通信.我把Server端得到的socke ...

  8. tcp 服务端如何判断客户端断开连接

    一篇文章:   最近在做一个服务器端程序,C/S结构.功能方面比较简单就是client端与server端建立连接,然后发送消息给server.我在server端会使用专门的线程处理一条socket连接 ...

  9. Tcp服务端判断客户端是否断开连接

    今天搞tcp链接弄了一天,前面创建socket,绑定,监听等主要分清自己的参数,udp还是tcp的.好不容易调通了,然后就是一个需求,当客户端主动断开连接时,服务端也要断开连接,这样一下次客户端请求链 ...

随机推荐

  1. 获取ORACLE数据库的构建信息

    首先连接到数据库,获取ORACLE数据库的基本信息: C:\USERS\ADMINISTRATOR>SQLPLUS/NOLOG SQL*PLUS: RELEASE 10.2.0.3.0 - PR ...

  2. Swift笔记

    最近从Xcode6 beta4开始到现在的Xcode6.0.1,使用Swift一段时间了,Swift大体来说,语法与java.c++比较接近,相比objective-c要友好多了,也更容易上手,这里记 ...

  3. bzoj 3531 旅行

    动态开点线段树+树链剖分  对于每一种宗教信仰都开一颗线段树 空间: QlogN 即每一次修改都只会改变logN 个点 时间 O(QlogN)  naive题  边没有开两倍  QAQ bzoj 35 ...

  4. Codeforces Round #167 (Div. 2)

    C. Dima and Staircase 线段树维护区间最大值. D. Dima and Two Sequences 由于模数不一定为质数,所以通过拆分质因数来做阶乘取模. E. Dima and ...

  5. ns115 step by step

    一,安装环境: sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev lib ...

  6. 另类vs2015+xamarin 的android界面乱码 解决

    text.Text += "验证key 验证出错! 请在 AndroidManifest.xml 文件中检查 key 设置"; 代码就上面一行,单步走之前text.Text里面是汉 ...

  7. (转)Image Segmentation with Tensorflow using CNNs and Conditional Random Fields

    Daniil's blog Machine Learning and Computer Vision artisan. About/ Blog/ Image Segmentation with Ten ...

  8. Lua词汇约定

    Lua的标识符包含数字,字母以及下划线,数字不能作为标识符的开头. and break do else elseif end false for function goto if in local n ...

  9. Ninject使用介绍

    #region 第二种写法 /// <summary> /// using(IKernel tKernel=new StandardKernel(new PeoKernelServer() ...

  10. sql server2008 检查是否需要挂起计算机重新启动。挂起重新启动会导致安装程序失败。

    解决方法: 1.如果重新启动后,一样无效, 2.那么就进入注册表编辑器,通过修改注册表的方法来解决.除了删除SQL安装时遗留下的LJ文件,还必须进行以下操作: 在"开始"-&quo ...