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/

转载于:https://www.cnblogs.com/yxlwb/p/7204229.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值