Java Sockets

0

Witam.
Korzystając z tego tutoriala: http://cs.lmu.edu/~ray/notes/javanetexamples/#chat próbowałem stworzyć aplikację działającą na socketach. Dokładniej czat.
Stworzyłem sobie 5 klas:
ChatClient - odpowiada za gui oraz komunikację z serwerem
CommunicationServer - serwer tworzący ServerSocket i nasłuchujący kolejnych klientów
CommunicationServerConsole - aplikacja okienkowa - konsola serwera (przekierowuje System.out na textArea tego frame'a)
TextAreaPrintStream - klasa, która pozwala mi wypisać w textArea treści, które są wypisywane na konsolę
CommunicationHandler - klasa odpowiadająca za inicjalizację oraz komunikację z klientem

Niestety pojawił się problem: aplikacja zawiesza się na linii, która próbuje wypisać na OutputStream klienta tekst (CommunicationHandler.java:52) nie pokazując żadnego komunikatu, ani Exceptiona. Pozwoliłem sobie usunąć importy oraz gettery i settery w kodach źródłowych oraz nie dołączyłem pliku TextAreaPrintStream, ponieważ nie ma on żadnego znaczenia w moim problemie. Klasą startującą dla serwera jest CommunicationServerConsole, dla klienta - ChatClient.

@SuppressWarnings("serial")
public class CommunicationServerConsole extends JPanel {

    private JTextArea textArea = new JTextArea(15, 30);
    private TextAreaPrintStream taps = new TextAreaPrintStream(
            textArea, "Server");

    public CommunicationServerConsole() {
        setLayout(new BorderLayout());
        add(new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
        System.setOut(taps);
        textArea.setEnabled(false);
        textArea.setFont(new Font("Arial Unicode MS", Font.PLAIN, 12));
        textArea.setBackground(Color.BLACK);
    }

    private static void init() {
        JFrame frame = new JFrame("Communication Server Console");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new CommunicationServerConsole());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {

        init();
        CommunicationServer.getInstance();
    }
}
final public class CommunicationServer {

    private static volatile CommunicationServer instance = null;
    private static final int PORT = 9001;
    private HashMap<String, PrintWriter> clients = new LinkedHashMap<String, PrintWriter>();

    private CommunicationServer() {
        try {
            System.out.println("Initializing server chat...");
            createServer();
        } catch (IOException ex) {
            Logger.getLogger(CommunicationServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static CommunicationServer getInstance() {
        if (instance == null) {
            synchronized (CommunicationServer.class) {
                if (instance == null) {
                    instance = new CommunicationServer();
                }
            }
        }
        return instance;
    }
    
    public void createServer() throws IOException {
        ServerSocket serverSocket = new ServerSocket(PORT);
        System.out.println("Server was created successfully.");
        try {
            while (true) {
                new CommunicationHandler(serverSocket.accept()).start();
            }
        } finally {
            serverSocket.close();
        }
    }
}
public class CommunicationHandler extends Thread {

    private String nick;
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;

    public CommunicationHandler(Socket socket) {
        super();
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream());

            createNickname();
            listening();

        } catch (IOException ex) {
            Logger.getLogger(CommunicationHandler.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            if (nick != null) {
                CommunicationServer.getInstance().getClients().remove(nick);
            }
            try {
                socket.close();
            } catch (IOException ex) {
                Logger.getLogger(CommunicationHandler.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private void createNickname() throws IOException {
        while (true) {
            out.println("$nick");
            nick = in.readLine();
            if (nick == null || "".equals(nick)) {
                return;
            }
            synchronized (CommunicationServer.getInstance().getClients()) {
                if (!CommunicationServer.getInstance().getClients().containsKey(nick)) {
                    CommunicationServer.getInstance().getClients().put(nick, out);
                    out.println("$nickaccepted");
                    break;
                } else {
                    out.println("Nickname is occupied.");
                }
            }
        }
    }

    private void listening() throws IOException {
        while (true) {
            String input = in.readLine();
            if (input == null || "".equals(input)) {
                return;
            }
            for (PrintWriter writer : CommunicationServer.getInstance().getClients().values()) {
                writer.println("MSG " + nick + ": " + input);
            }
        }
    }
}
public class ChatClient {

    private Boolean isConnected = false;
    private BufferedReader in;
    private PrintWriter out;
    private JFrame frame = new JFrame("Chat");
    private JTextField textField = new JTextField(40);
    private JTextArea messageArea = new JTextArea(8, 40);

    public ChatClient() {
        textField.setEditable(false);
        messageArea.setEditable(false);
        frame.getContentPane().add(textField, "North");
        frame.getContentPane().add(new JScrollPane(messageArea), "Center");
        frame.pack();

        textField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                out.println(textField.getText());
                textField.setText("");
            }
        });
    }

    private String getServerAddress() {
        return JOptionPane.showInputDialog(
                frame,
                "Enter IP Address of the Server:",
                "Welcome to the chat",
                JOptionPane.QUESTION_MESSAGE);
    }

    private String getName() {
        return JOptionPane.showInputDialog(
                frame,
                "Choose a screen name:",
                "Screen name selection",
                JOptionPane.PLAIN_MESSAGE);
    }

    private void connectToServer() throws UnknownHostException, IOException {
        String serverAddress = getServerAddress();
        Socket socket = new Socket(serverAddress, 9001);
        in = new BufferedReader(new InputStreamReader(
                socket.getInputStream()));
        out = new PrintWriter(socket.getOutputStream(), true);
        isConnected = true;
    }

    private void run() {

        do {
            try {

                connectToServer();
                
                while (true) {
                    String line = in.readLine();
                    if (line.startsWith("$nick")) {
                        out.println(getName());
                    } else if (line.startsWith("$nickaccepted")) {
                        textField.setEditable(true);
                    } else if (line.startsWith("MSG")) {
                        messageArea.append(line.substring(8) + "\n");
                    }
                }
            } catch (ConnectException | UnknownHostException e) {
                Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, "Nie odnaleziono hosta.");
            } catch (IOException e) {
                Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, "Błąd połączenia.");
            }
        } while (!isConnected);
    }

    public static void main(String[] args) throws Exception {
        ChatClient client = new ChatClient();
        client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        client.frame.setVisible(true);
        client.run();
    }
}

Proszę o pomoc.

0

Niestety zapomniałem, że linie się nie numerują, a poza tym zmieniła się ich ilość po wykasowaniu części kodu. Tak więc problem leży w tej linii:

out.println("$nick");

1 użytkowników online, w tym zalogowanych: 0, gości: 1