JAVA 判断Socket 远程端是否断开链接

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

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

  如下是示例代码仅供参考:socket

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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/6146749this

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

相关文章
相关标签/搜索