java socket 进阶话题一: socket 客户端连接管理(二)

2014-11-24 03:00:24 · 作者: · 浏览: 4
t: 64542 is close: false -- is connected: true


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


exec time: 2014-01-23 18:14:57


Exec time: 2014-01-23 18:14:40 设置socket 连接为关闭状态

从日志可以看出,在设置了第二个和第三个socket 为关闭状态后,server通过发送心跳消息,成功的判断客户端失去连接,这样就可以近似实时的判断
出代理端连接状态,当然你可以在查询某个连接的状态时,直接发送消息进行判断代理端的连接状态。