Потоки не работают должным образом на моем боте Java IRC - PullRequest
1 голос
/ 10 января 2012

Я не знаю точно, как работают потоки, но, думаю, я все делаю правильно.
Я пишу IRC-бот, чтобы помочь мне в администрировании некоторых компьютеров.

Когда бот получает команду -new , он запускает другого бота с заданными параметрами.
Бот правильно подключается к сети, но последний, получивший команду на запуск другой, перестает отвечать на команды администратора.

Вот класс бот :

public class IRCBot extends Thread {

    private final String NETWORK;
    private final int PORT;
    private String nickname;
    private String defaultChannel;
    private String admin;
    private Socket connection;
    private BufferedReader input;
    private BufferedWriter output;
    private final String VERSION = "1.00";

    public IRCBot(String NETWORK, int PORT, String nickname, String defaultChannel, String admin) {
        this.NETWORK = NETWORK;
        this.PORT = PORT;
        this.nickname = nickname;
        this.defaultChannel = defaultChannel;
        this.admin = admin;
    }

    private void connect() throws Exception {
        connection = new Socket(NETWORK, PORT);
        input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        output = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
    }

    private void disconnect() throws Exception {
        connection.close();
    }

    private void sendLoginData() throws Exception {
        output.write("NICK " + nickname + "\n");
        output.write("USER " + nickname + " codemonkey.com CM: " + nickname + "\n");
        output.flush();
    }

    private void pingPong(String[] data) throws Exception {
        if (data[0].equals("PING")) {
            System.out.println("--> PONG " + data[1]);
            output.write("PONG " + data[1] + "\n");
            output.flush();
        }
    }

    private void joinChannel(String channel) throws Exception {
        output.write("JOIN " + channel + "\n");
        output.flush();
    }

    private void sendMessage(String to, String message) throws Exception {
        System.out.println("--> PRIVMSG " + to + " :" + message + "\n");
        output.write("PRIVMSG " + to + " :" + message + "\n");
        output.flush();
    }

    private void verifyMOTD(String[] data) throws Exception {
        if (data.length >= 2) {
            /**
             * 376 is the protocol number (end of MOTD)
             */
            if (data[1].equals("376")) {
                joinChannel(defaultChannel);
                sendMessage(defaultChannel, "wazup monkeys!");
            }
        }
    }

    private boolean isCommand(String[] data) {
        if (data.length >= 4) {
            if (data[1].equals("PRIVMSG")) {
                String[] split = data[0].split("!");
                if (split[0].substring(1).equals(admin)) {
                    if (data[3].substring(1, 2).equals("-")) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private void verifyCommand(String[] data) throws Exception {
        if (isCommand(data)) {
            String from = data[2];
            String command = data[3].substring(2);
            switch (command) {
                case "admin":
                    sendMessage(from, admin);
                    break;
                case "version":
                    sendMessage(from, VERSION);
                    break;
                case "avapro":
                    sendMessage(from, String.valueOf(Runtime.getRuntime().availableProcessors()));
                    break;
                case "freememory":
                    sendMessage(from, String.valueOf(Runtime.getRuntime().freeMemory()));
                    break;
                case "totalmemory":
                    sendMessage(from, String.valueOf(Runtime.getRuntime().totalMemory()));
                    break;
                case "new":
                    if (data.length < 9) {
                        throw new WrongParametersException(from, "-new (network) (port) (nickname) (defaultChannel) (admin)");
                    }
                    IRCBot newBot = new IRCBot(data[4],Integer.parseInt(data[5]),data[6],data[7],data[8]);
                    Thread threadNewBot = new Thread(newBot);
                    threadNewBot.run();
                    break;
                default:
                    sendMessage(from, "exception -> uknown function: \"" + command + "\"");
                    break;
            }
        }
    }

    public void run() {
        try {
            connect();
            sendLoginData();

            while (true) {
                String data = null;
                while ((data = input.readLine()) != null) {
                    System.out.println("<-- " + data);
                    String[] dataSplitted = data.split(" ");
                    pingPong(dataSplitted);
                    verifyMOTD(dataSplitted);
                    try {
                        verifyCommand(dataSplitted);
                    } catch (WrongParametersException ex) {
                        sendMessage(ex.from(), ex.toString());
                    }
                }
            }
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }
}

А вот основной класс:

public class Main {
    public static void main(String[] args) {
        IRCBot bot = new IRCBot("irc.quakenet.org",6667,"cod3monk3y","#codemonkey","codemonkey");
        Thread botThread = new Thread(bot);
        botThread.run();
    }
}

1 Ответ

8 голосов
/ 10 января 2012

Вы вызываете run() в своей теме вместо start().

run() просто вызывает метод, который выполняет ваш код в том же потоке, в котором он был вызван.

start() фактически запускает новый поток и выполняет код для него.

...