HcgServer.java 10.4 KB
package cn.csbr.app.Long;

import cn.csbr.app.hardware.BWCabinetTestDll;
import cn.csbr.app.util.SystemUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

@Component
public class HcgServer {
    @Value("${longport}")
    private String longport;
    @Value("${longpwd}")
    private String longpwd;
    @Value("${maxcon}")
    private String maxcon;
    java.util.List<Socket> sockets=new ArrayList<Socket>();
    private volatile Date cleartime;//清除连接时间 为了防止僵尸连接每天晚上凌晨12点强制断开所有连接
    private volatile  boolean ischeck=false;//是否有盘点任务在执行//如果有盘点任务就挂起等待一起返回没有则直接发起盘点
    public void start(){
        new Thread(()->{
            try{
                ServerSocket server=null;
                try{
                    //创建一个ServerSocket在端口longport监听客户请求
                    server=new ServerSocket(Integer.parseInt(longport));
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String s = sdf.format(new Date());
                    cleartime =  sdf.parse(s);
                    new Thread(()->{xt();}).start();//启动心跳线程
                }catch(Exception e){
                    e.printStackTrace();//出错,打印出错信息
                }
                Socket socket=null;
                while (true) {
                    try {
                        System.out.println("开始监听请求");
                        //使用accept()阻塞等待客户请求,有客
                        socket = server.accept();//请求到来则产生一个Socket对象,并继续执行
                        System.out.println("检查到:"+socket.getLocalAddress().getHostAddress()+":"+socket.getPort());
                        //由Socket对象得到输出流,并构造PrintWriter对象
                        PrintWriter os = new PrintWriter(socket.getOutputStream());
                        BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        if (sockets.size() >= Integer.parseInt(maxcon)) {
                            os.print("lj:NO:连接数量超过系统支持");
                            os.flush();
                            socket.close();
                        } else {
                            String[] message = is.readLine().split(":");
                            if (message.length != 2) {
                                os.print("lj:NO:非法操作;");
                                os.flush();
                                socket.close();
                            } else {
                                if (!message[0].equals("pwd")) {
                                    os.print("lj:NO:非法操作;");
                                    os.flush();
                                    socket.close();
                                } else {
                                    if (message[1].equals(longpwd)) {
                                        System.out.println("已经受理" + socket.getLocalAddress().getHostAddress() + ":" + socket.getPort() + "的连接请求");
                                        os.print("lj:YES:连接成功;");
                                        os.flush();
                                        Socket finalSocket = socket;
                                        new Thread(() -> {
                                            try {
                                                work(finalSocket);
                                            } catch (Exception e) {
                                                try {
                                                    finalSocket.close();
                                                } catch (IOException ex) {
                                                    ex.printStackTrace();
                                                }
                                            }
                                        }).start();
                                        sockets.add(socket);
                                    } else {
                                        os.print("lj:NO:密码错误;");
                                        os.flush();
                                        socket.close();
                                    }
                                }
                            }
                            // os.close();
                            //is.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();//出错,打印出错信息
                        if(socket!=null){
                            socket.close();
                        }
                    }
                }
            }catch(Exception e){
                e.printStackTrace();//出错,打印出错信息
            }
        }).start();
    }
    private void work(Socket socket) throws IOException, InterruptedException {
        String line;
        PrintWriter os=new PrintWriter(socket.getOutputStream());
        BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        line=is.readLine();
        while (socket.isConnected()&&!line.equals("bye")){
            String[] cmd=line.split(":");
            if(cmd.length!=2){
                os.print(cmd[0]+":NO:非法操作;");
                os.flush();
                break;
            }else {
                synchronized (new Object()) {
                    System.out.println("开始执行"+socket.getLocalAddress()+":"+socket.getLocalPort()+"的远程指令:"+cmd[0]);
                    try {
                        if (cmd[0].equals("reshutdown")) {
                            SystemUtil.ReHcg();
                            os.print(cmd[0] + ":YES:xxxxx;");
                        } else if (cmd[0].equals("opendoor")) {
                            BWCabinetTestDll instance = BWCabinetTestDll.instance;
                            String msg = "";
                            int reflag = instance.BWUnlockDoor(Integer.parseInt(cmd[1]));
                            //int reflag=0;
                            if (reflag == 0) {
                                msg = "YES:开锁成功";
                            } else {
                                msg = "NO:开锁失败" + reflag;
                            }
                            os.print(cmd[0]+":"+msg);
                        } else {
                            os.print(cmd[0] + ":NO:xxxxx;");
                        }
                    }catch (Exception ex){
                        os.print(cmd[0]+":NO:"+ex.getMessage());
                    }catch (Error er){
                        os.print(cmd[0]+":NO:"+er.getMessage());
                    }
                    os.flush();
                    Thread.sleep(1000);
                }
            }
            line=is.readLine();
        }
        System.out.println(socket.getRemoteSocketAddress()+":主动断开连接");
        socket.close();
        is.close();
        os.close();
    }
    //心跳所有心跳必须回复不然直接强行断开连接
    private void xt(){
        System.out.println("心跳线程启动");
        while (true) {
            try {
                Thread.sleep(10000);//每十秒检查一次心跳
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String s = sdf.format(new Date());
            Date newcleartime=null;
            try {
                newcleartime =  sdf.parse(s);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            if(newcleartime!=null){
                if((newcleartime.getTime() - cleartime.getTime()) / (24 * 60 * 60 * 1000)==1){
                    System.out.println(new Date().toString()+":开始断开所有连接");
                    cleartime= newcleartime;
                    for (int i = 0; i < sockets.size(); i++) {
                        try {
                            sockets.remove(i);
                            sockets.get(i).close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            for (int i = 0; i < sockets.size(); i++) {
                Socket item = sockets.get(i);
                try {
                    if(!item.isConnected()){
                        System.out.println(item.getRemoteSocketAddress()+"未检测到心跳被强制断开1");
                        try {
                            sockets.remove(i);
                            item.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        continue;
                    }
                    String line;
                    PrintWriter os = new PrintWriter(item.getOutputStream());
                    BufferedReader is = new BufferedReader(new InputStreamReader(item.getInputStream()));
                    os.print("xt;");
                    os.flush();
                    line = is.readLine();
                    if (line.equals("sd;")) {
                        continue;
                    } else {
                        System.out.println(item.getRemoteSocketAddress()+"未检测到心跳被强制断开2");
                        try {
                            sockets.remove(i);
                            item.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                } catch (Exception ex) {
                    System.out.println(item.getRemoteSocketAddress()+"未检测到心跳被强制断3");
                    try {
                        sockets.remove(i);
                        item.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}