通过线程监控socket服务器是否done机详解编程语言

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

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

通过线程监控socket服务器是否done机详解编程语言

通过线程监控socket服务器是否done机详解编程语言

 

因为线程是每两秒发送一次请求检测服务器是否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服务器是否done机详解编程语言

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

 转载请注明出处。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/11497.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论