JAVA 判斷Socket 遠程端是否斷開連接


最近在做項目的時候,遇到這樣一個問題,如何判斷 Socket 遠程端連接是否關閉,如果關閉的話,就要重建連接Socket的類提供了一些已經封裝好的方法, 如  isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等,在測試時發現,這些方法都是本地端的狀態,無法判斷遠端是否已經斷開連接。

  其實在socket類中有一個方法sendUrgentData,它會往輸出流發送一個字節的數據,只要對方Socket的SO_OOBINLINE屬性沒有打開,就會自動舍棄這個字節(在Java 中是拋出異常),而SO_OOBINLINE屬性默認情況下就是關閉的。

  以下是示例代碼僅供參考:

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/6146749

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM