Prosty czat - problem z odłączającym się klientem

0

Hej, napisałem prościutki program czat w Javie. Jednak po odłączeniu się przez jednego klienta, drugi klient/inni widzą, że ten, który się odłączył ciągle wysyła na czat wiadomość null ... chociaż go na czacie już nie ma:/

Kod klienta:


import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import javax.swing.ListModel;
import java.net.*;

public class MultiClient {

    public static void main(String[] args) throws IOException, InterruptedException {
        new Client();
    }
}

class Client extends javax.swing.JFrame implements Runnable {

    private Socket socket;
    private DataInputStream in;
    private PrintStream out;
    private String name;
    private List<PrivateWindow> listPrivateWindow;

    public Client() throws IOException {
        name = JOptionPane.showInputDialog("Podaj swoje imie");
        if (name == null || name.equals("")) {
            System.exit(0);
        }

        initComponents();
        setLocationRelativeTo(null);
        setVisible(true);
        listPrivateWindow = new ArrayList<PrivateWindow>();

        try {
            socket = new Socket("localhost", 8080);
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, "Nie mozna sie polaczyc z serwerem", "Informacja", 1);
            System.exit(0);
        }

        try {
            in = new DataInputStream(socket.getInputStream());
            out = new PrintStream(socket.getOutputStream());
            new Thread(this).start();

            out.println(name);
        } catch (IOException e) {
            socket.close();
        }
    }

    private void sendMessage() {
        out.println(textField.getText());
        textField.setText(null);
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        textArea = new javax.swing.JTextArea();
        jScrollPane2 = new javax.swing.JScrollPane();
        listPerson = new javax.swing.JList();
        jLabel1 = new javax.swing.JLabel();
        textField = new javax.swing.JTextField();
        buttonSend = new javax.swing.JButton();
        countPerson = new javax.swing.JLabel();
        buttonPrivate = new javax.swing.JButton();
        buttonFile = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Chat Client v. 1.0");
        setMinimumSize(new java.awt.Dimension(800, 600));
        setResizable(false);

        textArea.setColumns(20);
        textArea.setEditable(false);
        textArea.setRows(5);
        jScrollPane1.setViewportView(textArea);

        jScrollPane2.setViewportView(listPerson);

        jLabel1.setText("Osób na kanale:");

        textField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                textFieldKeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                textFieldKeyReleased(evt);
            }
        });

        buttonSend.setText("Wyślij");
        buttonSend.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonSendActionPerformed(evt);
            }
        });

        countPerson.setText("0");

        buttonPrivate.setText("Prywatna rozmowa");
        buttonPrivate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonPrivateActionPerformed(evt);
            }
        });

        buttonFile.setText("Wyślij plik");
        buttonFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonFileActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(textField, javax.swing.GroupLayout.DEFAULT_SIZE, 553, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonSend))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(buttonFile, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(buttonPrivate, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jLabel1)
                            .addGap(30, 30, 30)
                            .addComponent(countPerson))
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)))
                .addGap(13, 13, 13))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 531, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(textField, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(buttonSend)))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel1)
                            .addComponent(countPerson))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(buttonPrivate, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(buttonFile, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>

    private void buttonSendActionPerformed(java.awt.event.ActionEvent evt) {                                           
        sendMessage();
    }                                          

    private void buttonPrivateActionPerformed(java.awt.event.ActionEvent evt) {                                              
        if (listPerson.getSelectedValue() != null) {
            String addressee = listPerson.getSelectedValue().toString();
            if (addressee.equals(name)) {
                JOptionPane.showMessageDialog(this, "Nie mozesz rozmawiac sam ze soba!", "Informacja", 1);
            } else {
                try {
                    boolean isNew = true;
                    for (PrivateWindow pw : listPrivateWindow) {
                        if ((pw.getNadawca().equals(name) && pw.getAdresat().equals(addressee)) || (pw.getNadawca().equals(addressee) && pw.getAdresat().equals(name))) {
                            isNew = false;
                            pw.setVisible(true);
                        }
                    }
                    if (isNew) {
                        listPrivateWindow.add(new PrivateWindow(name, addressee));
                    }
                } catch (IOException ex) {
                    Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } else {
            JOptionPane.showMessageDialog(this, "Nie zaznaczyles zadnego rozmowcy!", "Informacja", 1);
        }
    }                                             

    private void buttonFileActionPerformed(java.awt.event.ActionEvent evt) {                                           
        if (listPerson.getSelectedValue() != null) {
            String addressee = listPerson.getSelectedValue().toString();
            if (addressee.equals(name)) {
                JOptionPane.showMessageDialog(this, "Po co chcesz sam sobie wyslac plik Drogi Uzytkowniku?", "Informacja", 1);
            } else {
                JOptionPane.showMessageDialog(this, "Mialo byc, ale nie zdazylem dopisac:)", "Informacja", 1);
            }
        } else {
            JOptionPane.showMessageDialog(this, "Nie zaznaczyles zadnego rozmowcy!", "Informacja", 1);
        }
    }                                          

    private void textFieldKeyReleased(java.awt.event.KeyEvent evt) {                                      
        if (evt.getKeyCode() == 10) {
            textField.setText(null);
        }
    }                                     

    private void textFieldKeyPressed(java.awt.event.KeyEvent evt) {                                     
        if (evt.getKeyCode() == 10) {
            out.println(textField.getText());
        }
    }                                    

    public void run() {
        String line;
        try {
            while ((line = in.readLine()) != null) {
                if (line.startsWith("code1;"))//ilosc uzytkownikow na liscie
                {
                    int index = line.indexOf(";");
                    line = line.substring(index + 1);
                    countPerson.setText(line);
                } else if (line.startsWith("code2;"))//dochodzi jeden nowy
                {
                    int index = line.indexOf(";");
                    line = line.substring(index + 1);

                    DefaultListModel list = new DefaultListModel();
                    ListModel listModel = listPerson.getModel();
                    for (int i = 0; i < listModel.getSize(); i++) {
                        list.addElement(listModel.getElementAt(i));
                    }
                    list.addElement(line);
                    listPerson.setModel(list);
                } else if (line.startsWith("code3;"))//dla nowego wczytuje cala liste
                {
                    int index = line.indexOf(";");
                    line = line.substring(index + 1);

                    DefaultListModel list = new DefaultListModel();
                    String nameClient;
                    while ((index = line.indexOf(";")) != -1) {
                        nameClient = line.substring(0, index);
                        line = line.substring(index + 1);
                        list.addElement(nameClient);
                    }

                    listPerson.setModel(list);
                } else if (line.startsWith("code4;"))//usuwam jednego ktory wyszedl
                {
                    int index = line.indexOf(";");
                    line = line.substring(index + 1);

                    DefaultListModel list = new DefaultListModel();
                    ListModel listModel = listPerson.getModel();
                    for (int i = 0; i < listModel.getSize(); i++) {
                        if (!listModel.getElementAt(i).toString().equals(line)) {
                            list.addElement(listModel.getElementAt(i));
                        }
                    }
                    listPerson.setModel(list);
                } else if (line.startsWith("private;")) {
                    // out.println("private;nadawca;" + this.nadawca + ";adresat;" + this.adresat + ";" + textField.getText());
                    int index = line.indexOf(";");
                    line = line.substring(index + 1);
                    index = line.indexOf(";");
                    line = line.substring(index + 1);
                    index = line.indexOf(";");

                    String nadawca = line.substring(0, index);
                    line = line.substring(index + 1);
                    index = line.indexOf(";");
                    line = line.substring(index + 1);
                    index = line.indexOf(";");
                    String adresat = line.substring(0, index);

                    String wiadomosc = line.substring(index + 1);

                    //System.out.println("nadawca " + nadawca);
                    //System.out.println("adresat " + adresat);
                    //System.out.println("wiadomosc " + wiadomosc);

                    if (this.name.equals(adresat)) {
                        boolean isNew = true;
                        for (PrivateWindow pw : listPrivateWindow) {
                            if ((pw.getNadawca().equals(nadawca) && pw.getAdresat().equals(adresat)) || (pw.getNadawca().equals(adresat) && pw.getAdresat().equals(nadawca))) {
                                isNew = false;
                                pw.setVisible(true);
                            }
                        }
                        if (isNew) {
                            listPrivateWindow.add(new PrivateWindow(adresat, nadawca, "<" + nadawca + ">" + wiadomosc));
                        }
                    }
                } else {
                    textArea.append(line + "\n");
                }
            }
        } catch (IOException e) {
            System.out.println("Błąd");
        }
    }
    // Variables declaration - do not modify
    private javax.swing.JButton buttonFile;
    private javax.swing.JButton buttonPrivate;
    private javax.swing.JButton buttonSend;
    private javax.swing.JLabel countPerson;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JList listPerson;
    private javax.swing.JTextArea textArea;
    private javax.swing.JTextField textField;
    // End of variables declaration
}

Tu cały projekt, jeśli komuś nie chce się patrzeć na forum w kod: http://www.speedyshare.com/BcM8z/Chat.tar.gz

1
  1. Napisz ten kod od nowa, bo ten woła o pomstę do nieba...
  2. Błąd zapewne masz w serwerze a nie w kliencie. Zgaduje że odbierasz dane na jana łapiąc wyjątek z socketu na pałę i niezależnie od tego czy wyjątek polecial czy nie wysyłasz do innych klientów to co "odebrałeś" z socketu. Oczywiście socket umarł razem z klientem więc nie odbierasz nic, ale łykasz wyjątek jak młody pelikan więc tego nie widzisz. Oczywiście to tylko moje dywagacje ;]

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