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

相關文章
相關標籤/搜索