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 socketList = new ConcurrentLinkedQueue();
/**
* 程序入口函数
* @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 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 连接为关闭状态");
}
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 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();
}
}
exec time: 2014-01-23 18:14:55