Exec time: 2014-01-23 15:49:30 设置socket 连接为关闭状态
在客户端设置其中一个socket 连接状态为关闭同时应用程序退出了,此时从server 端获取到的socket 状态依旧为可用状态。
我们怎么办,如何能真正的获取到socket的连接状态,答案就是:心跳,我们可以这样,在代码中增加如下功能:
server 端监控代码如下:
public void run() {
while (true) {
Socket socketOut = null;
try {
Thread.sleep(2000);
System.out.println("exec time: " + DateHelper.date2String(new Date()));
for (Socket socketTemp : socketList) {
socketOut = socketTemp;
System.out.println("ip: " + socketTemp.getInetAddress().getHostAddress() + " -- remote port: "
+ socketTemp.getPort() + " is close: " + socketTemp.isClosed() + " -- is connected: "
+ socketTemp.isConnected());
//心跳,发送消息用来真正的检验客户端是否存在
DataOutputStream dataOut = new DataOutputStream( socketTemp.getOutputStream());
dataOut.writeBytes("test");
dataOut.flush();
}
System.out.println("\n");
}
catch (Exception e) {
//出现异常,删除掉出现错误的客户端
socketList.remove(socketOut);
System.out.println(e.getMessage());
}
}
}
客户端代码如下:
public static void main(String[] args) {
try {
List
listSocket = new ArrayList
(); for(int i=0 ;i < 5 ;i++){ Socket socket = new Socket("localhost", 9912); listSocket.add(socket); } Thread.sleep(4000); Socket socket = listSocket.get(2); socket.close(); Socket socket1 = listSocket.get(3); socket1.close(); socket1 = null; System.out.println("Exec time: " + DateHelper.date2String(new Date()) + " 设置socket 连接为关闭状态"); Thread.sleep(8000); } catch (Exception e) { e.printStackTrace(); } }
server 端增加心跳控制,向代理端发送心跳消息,客户端在设置socket 为关闭后,等待8秒钟然后退出
结果输出如下:
exec time: 2014-01-23 18:14:39
ip: 127.0.0.1 -- remote port: 52669 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52670 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52671 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52674 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52675 is close: false -- is connected: true
exec time: 2014-01-23 18:14:41
ip: 127.0.0.1 -- remote port: 52669 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52670 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52671 is close: false -- is connected: true
Software caused connection abort: socket write error
exec time: 2014-01-23 18:14:43
ip: 127.0.0.1 -- remote port: 52669 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52670 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52674 is close: false -- is connected: true
Software caused connection abort: socket write error
exec time: 2014-01-23 18:14:45
ip: 127.0.0.1 -- remote port: 52669 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52670 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52675 is close: false -- is connected: true
exec time: 2014-01-23 18:14:47
ip: 127.0.0.1 -- remote port: 52669 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52670 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 52675 is close: false -- is connected: true
exec time: 2014-01-23 18:14:49
ip: 127.0.0.1 -- remote port: 52669 is close: false -- is connected: true
Connection reset by peer: socket write error
exec time: 2014-01-23 18:14:51
ip: 127.0.0.1 -- remote port: 52670 is close: false -- is connected: true
Connection reset by peer: socket write error
exec time: 2014-01-23 18:14:53
ip: 127.0.0.1 -- remote port: 52675 is close: false -- is connected: true
Connection reset by peer: socket write error
exec time: 2014-01-23 18:14:55
从日志可以看出,在设置了第二个和第三个socket 为关闭状态后,server通过发送心跳消息,成功的判断客户端失去连接,这样就可以近似实时的判断
出代理端连接状态,当然你可以在查询某个连接的状态时,直接发送消息进行判断代理端的连接状态。