java socket 提供的方法 isConnected() 和 isClosed 无法真正的检测出客户端的状态,请看代码:
socket 服务端代码:
package com.test.socket.state; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; import java.util.concurrent.ConcurrentLinkedQueue; import com.zsmart.core.common.DateHelper; /** * socket 服务端 * @author chm * */ public class ServerSocketTest { /**存放客户端连接集合*/ public static ConcurrentLinkedQueue<Socket> socketList = new ConcurrentLinkedQueue<Socket>(); /** * 程序入口函数 * @param args */ public static void main(String[] args) { ServerSocketTest sst = new ServerSocketTest(); sst.startMonitor(); } /** * 监控客户端连接 */ public void startMonitor() { try { ServerSocket serverS = new ServerSocket(9912); Thread th = new Thread(new MonitorClientState()); th.start(); while (true) { Socket socket = serverS.accept(); socketList.add(socket); } } catch (Exception e) { e.printStackTrace(); } } /** * 客户端状态监控类 * @author chm * */ class MonitorClientState implements Runnable { public void run() { try { while(true){ Thread.sleep(2000); System.out.println("exec time: " + DateHelper.date2String(new Date())); for(Socket socketTemp : socketList){ System.out.println("ip: " + socketTemp.getInetAddress().getHostAddress() + " -- remote port: " + socketTemp.getPort() + " is close: " + socketTemp.isClosed() + " -- is connected: " + socketTemp.isConnected()); } } } catch (Exception e) { e.printStackTrace(); } } } }
socket 客户端代码:
package com.test.socket.state; import java.net.Socket; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.zsmart.core.common.DateHelper; /** * 客户端socket * @author chm * */ public class ClientSocket { public static void main(String[] args) { try { List<Socket> listSocket = new ArrayList<Socket>(); 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 连接为关闭状态"); } catch (Exception e) { e.printStackTrace(); } } }
exec time: 2014-01-23 15:49:29
ip: 127.0.0.1 -- remote port: 64538 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64539 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64540 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64541 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64542 is close: false -- is connected: true
exec time: 2014-01-23 15:49:31
ip: 127.0.0.1 -- remote port: 64538 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64539 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64540 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64541 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64542 is close: false -- is connected: true
exec time: 2014-01-23 15:49:33
ip: 127.0.0.1 -- remote port: 64538 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64539 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64540 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 64541 is close: false -- is connected: true
ip: 127.0.0.1 -- remote port: 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<Socket> listSocket = new ArrayList<Socket>(); 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(); } }
exec time: 2014-01-23 18:14:55
java socket 进阶话题一: socket 客户端连接管理
原文:http://blog.csdn.net/softhome/article/details/18711701