zoukankan      html  css  js  c++  java
  • 通过线程监控socket服务器是否done机

    现实中的socket可能会因为各种原因done机,但这么重要的服务器怎么能允许这种事情发生?这次我们就来通过一个线程去监控socket服务器,如果done机重新将其启动。

    下面是监控项目和socket服务器项目的目录结构:

    因为线程是每两秒发送一次请求检测服务器是否done机,类似心跳,所以包名起作heart。

    来看客户端heart代码:

    Entity 实体类:用来构建测试请求的数据结构

    package heart;
    
    import java.io.Serializable;
    
    public class Entity implements Serializable {
    
        private static final long serialVersionUID = 1L;
        private String name;
        private String sex;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        @Override
        public String toString() {
            return "Entity [name=" + name + ", sex=" + sex + "]";
        }
    
    }

    客户端同步线程代码:

    package heart;
    
    public class ClientHeart extends Thread {
    
        @Override
        public void run() {
    
            try {
                while (true) {
                    ClientSender.getInstance().send();
                    synchronized (ClientHeart.class) {
                        // this.wait(5000);
                        Thread.sleep(2000);
                    }
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 程序的入口main方法
         * 
         * @param args
         */
        public static void main(String[] args) {
            ClientHeart client = new ClientHeart();
            client.start();
        }
    
    }

    客户端发送消息代码:

    package heart;
    
    import java.io.ObjectOutputStream;
    import java.net.InetAddress;
    import java.net.Socket;
    
    import echoserver.EchoServer;
    import heart.Entity;
    
    public class ClientSender {
    
        private ClientSender() {
        }
    
        Socket sender = null;
        private static ClientSender instance;
    
        public static ClientSender getInstance() {
            if (instance == null) {
                synchronized (ClientHeart.class) {
                    instance = new ClientSender();
                }
            }
            return instance;
        }
    
        @SuppressWarnings("static-access")
        public void send() {
            try {
                sender = new Socket("192.168.1.166", 9090);
                
                while (true) {
                    ObjectOutputStream out = new ObjectOutputStream(sender.getOutputStream());
                    Entity obj = new Entity();
                    obj.setName("xiaoming");
                    obj.setSex("男");
                    out.writeObject(obj);
                    out.flush();
    
                    System.out.println("已发送...");
                    Thread.sleep(5000);
                }
            } catch (Exception e) {
                EchoServer myServer = new EchoServer();
                System.out.println("连接异常");
                try {
                    myServer.main(null);
                } catch (Exception e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                
            }
        }
    }

    发送消息代码中,可以看到socket是重新起的一个socket,和socket服务器并无关联,与服务器中的heart代码中的服务器相对应(如果加上监控socket的服务器,服务器项目中其实是有两个服务器的,一个作为socket服务器,一个作为监控socket的服务器),这样就可以避免一直重新new出socket造成的channel异常。

    一开始我选择用过quartz定时器作为轮巡监测,也试着搭建过webservice,但是都失败了。quartz轮巡会造成socket服务器的阻塞,webservice的话,如果服务器done机,那么这个webservice也就跟着一起done掉了,更不要谈什么监测了,所以,创建一个单线程的监测,速度又快(2秒一次完全够了),又安全,何乐不为?

    注意,客户端的config包中的xml配置文件其实是和服务器中的一模一样的,我是在监测服务器的项目中为了能够在服务器done机后重新启动服务器,在buildPath中加入了服务器的项目,但是服务器项目中需要引用EchoServer.xml这个文件,所以在客户端重新复制了一份。

    以下是服务器端的监测线程:

    package heart;
    
    import java.io.ObjectInput;
    import java.io.ObjectInputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import heart.Entity;
    
    
    public class ServerHeart extends Thread {
    
        private ServerSocket server = null;
        Object obj = new Object();
    
        @Override
        public void run() {
            try {
                server = new ServerSocket(9090);
    
                while (true) {
                    Socket client = server.accept();
                    synchronized (obj) {
                        new Thread(new Client(client)).start();
                    }
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 客户端线程
         * 
         * @author USER
         *
         */
        class Client implements Runnable {
            Socket client;
    
            public Client(Socket client) {
                this.client = client;
            }
    
            @Override
            public void run() {
                try {
                    while (true) {
                        ObjectInput in = new ObjectInputStream(client.getInputStream());
                        Entity entity = (Entity) in.readObject();
                        System.out.println(entity);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * 程序的入口main方法
         * 
         * @param args
         */
        public static void main(String[] args) {
            System.out.println("开始检测服务器是否done机...");
            new ServerHeart().start();
        }
    }

    下面附上两个项目的传送门:http://files.cnblogs.com/files/fengwenzhee/monitorSocket.rar

    另外:SSsocket(服务器项目)中有一个Test.jar文件,这个可不是jar包,里面是socket服务器的测试原件,直接解压就可以用了。

    如果要在linux系统测试,就把两个项目打成可执行的jar(runnable JAR file),然后导入linux虚拟机中(我是通过putty这个辅助软件导入的)地址:http://files.cnblogs.com/files/fengwenzhee/putty.rar,命令在我另一篇博客中有提到,然后jar -jar monitor.jar命令启动项目,(我是直接启动的监控项目,正好测试一下是否成功拉起done机的socket服务器)。

    测试成功,至于服务器的socket我用的是quicksocket,关于服务器有什么不明白的可以直接留言。

     转载请注明出处。

  • 相关阅读:
    【代码片段】HTML5嵌入媒体 (HTML5 Embedded Media)
    【代码片端】@Font-Face
    【代码片段】CSS3 渐变(CSS3 Gradients)
    【代码片段】CSS RESET,支持HTML5
    我的Cocos2d-x学习笔记(九)游戏帧循环(游戏主循环)
    我的Cocos2d-x学习笔记(八)利用CCSpriteBatchNode进行优化
    我的Cocos2d-x学习笔记(七)纹理缓存、帧缓存、精灵的创建、zOrder
    我的Cocos2d-x学习笔记(六)坐标体系与锚点
    我的Cocos2d-x学习笔记(五)CCLayer、CCLayerColor、CCLayerGradient、CCLayerMultiplex
    我的Cocos2d-x学习笔记(四)场景转换特效
  • 原文地址:https://www.cnblogs.com/fengwenzhee/p/7119546.html
Copyright © 2011-2022 走看看