zoukankan      html  css  js  c++  java
  • JAVA 判断Socket 远程端是否断开连接

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

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

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

    public class Nksocket extends Thread{  
    public String ip=null;//连接服务器的IP  
    public Integer port=null;//连接服务器的端口  
    private Socket socket=null;//套节字对象  
    private boolean close = false; // 关闭连接标志位,true表示关闭,false表示连接  
    private Integer sotimeout=1*1*10;//超时时间,以毫秒为单位  
    //------------------------------------------------------------------------------  
    public Nksocket(){  
       init();  
    }  
    public Nksocket(String ip,Integer port){  
       setIp(ip);  
       setPort(port);  
       init();  
    }  
    /** 
    * 初始化socket对象 
    */  
    public void init(){  
       try {  
        InetAddress address = InetAddress.getByName(getIp());  
        socket = new Socket(address,getPort());  
        socket.setKeepAlive(true);//开启保持活动状态的套接字  
        socket.setSoTimeout(sotimeout);//设置超时时间  
        close=!Send(socket,"2");//发送初始数据,发送成功则表示已经连接上,发送失败表示已经断开  
       }catch(UnknownHostException e) {  
        e.printStackTrace();  
       }catch(IOException e){  
        e.printStackTrace();  
       }  
    }  
    /** 
    * 读数据线程 
    */  
    public void run() {  
       while(true){  
        //---------读数据---------------------------  
        close = isServerClose(socket);//判断是否断开  
        if(!close){//没有断开,开始读数据  
         String readtext = ReadText(socket);  
         if(readtext!=null && readtext.trim().length()>0){  
          System.out.println("读取数据:"+readtext);  
         }  
        }  
        //---------创建连接-------------------------  
        while(close){//已经断开,重新建立连接  
         try{  
          System.out.println("重新建立连接:"+getIp()+":"+getPort());  
          InetAddress address = InetAddress.getByName(getIp());  
          socket = new Socket(address,getPort());  
          socket.setKeepAlive(true);  
          socket.setSoTimeout(sotimeout);  
          close = !Send(socket,"2");  
          System.out.println("建立连接成功:"+getIp()+":"+getPort());  
         }catch(Exception se){  
          System.out.println("创建连接失败:"+getIp()+":"+getPort());  
          close=true;  
         }  
        }  
       }  
    }  
    /** 
    * 发送数据,发送失败返回false,发送成功返回true 
    * @param csocket 
    * @param message 
    * @return 
    */  
    public Boolean Send(Socket csocket,String message){  
       try{  
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);  
        out.println(message);  
        return true;  
       }catch(Exception se){  
        se.printStackTrace();  
        return false;  
       }  
    }  
    /** 
    * 读取数据,返回字符串类型 
    * @param csocket 
    * @return 
    */  
    public String ReadText(Socket csocket){  
       try{  
        csocket.setSoTimeout(sotimeout);  
        InputStream input = csocket.getInputStream();  
        BufferedReader in = new BufferedReader(new InputStreamReader(input));  
        char[] sn = new char[1000];  
        in.read(sn);  
        String sc = new String(sn);  
        return sc;  
       }catch(IOException se){  
        return null;  
       }  
    }  
    /** 
    * 判断是否断开连接,断开返回true,没有返回false 
    * @param socket 
    * @return 
    */  
    public Boolean isServerClose(Socket socket){  
       try{  
        socket.sendUrgentData(0xFF);//发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信  
        return false;  
       }catch(Exception se){  
        return true;  
       }  
    }  
    /** 
    * 测试 
    * @param ags 
    */  
    public static void main(String[] ags){  
       Nksocket nksocket = new Nksocket("127.0.0.1",8090);  
       nksocket.start();  
    }  
    //------------------------------------------------------------------------------  
    public String getIp() {  
       return ip;  
    }  
    public void setIp(String ip) {  
       this.ip = ip;  
    }  
    public Integer getPort() {  
       return port;  
    }  
    public void setPort(Integer port) {  
       this.port = port;  
    }  
    }  
    

      

    参考资料:

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

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

  • 相关阅读:
    现代软件工程 第一周博客作业
    现代软件工程 课题初步调研 在线即时评教系统
    php判断网页是否gzip压缩
    采集练习(五) php 获得chrome扩展 微度新标签页 下的云壁纸(主要是美女壁纸)
    <raspberry pi> raspberry pi 设置wlan 静态ip
    采集练习(三) php 采集当当网图书的数据(初版)
    采集练习(六) python获得chrome扩展 微度新标签页 下的云壁纸
    采集练习(七) php 获得电视节目预告(一周节目)
    采集练习(八) php 获得网易精彩跟贴数据
    采集练习(四) python 获得hao123导航图片分类下的美女图片
  • 原文地址:https://www.cnblogs.com/wisdo/p/5859857.html
Copyright © 2011-2022 走看看