java中判断socket网络远端是否断开连接

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

最近在开发中遇到一个问题,就是如何判断远端服务器是否已经断开连接,如果断开那么需要重新连接。

首先想到socket类的方法isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,但经过试验并查看相关文档,这些方法都是本地端的状态,无法判断远端是否已经断开连接。

然后想到是否可以通过OutputStream发送一段测试数据,如果发送失败就表示远端已经断开连接,类似ping,但是这样会影响到正常的输出数据,远端无法把正常数据和测试数据分开。

最后又回到socket类,发现有一个方法sendUrgentData,查看文档后得知它会往输出流发送一个字节的数据,只要对方Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节,而SO_OOBINLINE属性默认情况下就是关闭的,太好了,正是我需要的!


java socekt 同步套节字编程主要用到java.net.Socket类,通常情况下我们需要socket的长连接模式。其次就是在连接的另一端断开之后需要及时响应。

对于连接的判断,socket提供的isClosed,isConnected等都是判断本地套节字的状态。要判断运程的连接,可以通过发送紧急数据来判断,紧急数据发送成功与否,就表示远程是否断开。


[java]  view plain copy
  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(0);//发送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",8089);  
  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. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值