EOFException в Клиент-Сервере зависает 2-й клиент Java

380
11 июня 2017, 17:09

Здравствуйте! Пишу общий чат. При каждом подключении Сервер создает новый поток, там проинициализированы:

output = new ObjectOutputStream (connection.getOutputStream ( )); //Пишем в чат input = new ObjectInputStream (connection.getInputStream ( )); //читаем с сервера

Поток при получении сообщения отправляет (output.writeObject()) всем другим потокам из списка подключенных пользователей.

Если 1 пользователь, то все работает. Но как только подключается 2 пользователь, 1 пользователь теряет способность отправлять сообщения, 2 пользователь отправляет и получает все как надо.

Если 1 пользователь отправляет сообщение, программа виснет, а потом выдает EOFException на стороне клиента при попытке чтения с сервера(input.readObject())

Полностью проект на GitHub: https://github.com/Evleaps/Messenger.git

Часть клиента:

private void Send(Object messagesText) {
    try {
        SimpleDateFormat date = new SimpleDateFormat ("HH:mm:ss");
        output.writeObject ( "\n" + Constant.LOGIN + ": "
                + date.format (new Date ()) + "\n"
                + messagesText.toString ());
        output.flush ();
        chat.setText (input.readObject().toString ()); //ТУТ ОШИБКА!!!!!!
        messages.setText ("");
    } catch (IOException e) {
        e.printStackTrace ( );
    } catch (ClassNotFoundException e) {
        e.printStackTrace ( );
    }
}

Cервер:

public class Server {
public static final int     PORT_MESSAGE = 7000;
private static ServerSocket server;
private static List<ConnectedClient> clients = Collections.synchronizedList ( new ArrayList<ConnectedClient> () );
private static StringBuffer historyMassages = new StringBuffer ("История сообщений: ");
/**
 * Сервер ждет подключение в бесконечном цикле, если есть подключение, отправляем в список подключенных клиентов
 * Список клиентов clients содержит каждого клиента как новый поток
 * Если в historyMassages больше 5000 символов, удаляем ранние сообщения
 */
public static void main(String[] args) throws IOException {
    try {
        new Thread (new CheckForOnline()).start ();//проверка: в сети ли пользователь?
        server = new ServerSocket (PORT_MESSAGE);
        while (true) {
            ConnectedClient client = new ConnectedClient (server.accept ( ));
            System.out.println ("Колличество клиентов main = " + clients.size () );
            clients.add (client);
            ConnectedClient.nameClient = client;
            client.start ( );
        }
    } catch (IOException e) {
        e.printStackTrace ( );
    } finally {
        server.close ();
    }
}
private static class ConnectedClient extends Thread {
    private static Socket connection;
    private static ObjectInputStream input;
    private static ObjectOutputStream output;
    protected static ConnectedClient nameClient;
    private static String messages;

    public ConnectedClient(Socket socket) throws IOException {
        connection = socket;
        System.out.println ("К серверу подключен пользователь...");
        output = new ObjectOutputStream (connection.getOutputStream ( )); //Пишем в чат
        input = new ObjectInputStream (connection.getInputStream ( )); //читаем с сервера
        output.writeObject (CheckForOnline.nameUser);
        output.flush ();
        System.out.println ("Сервер передал новому пользователю список занятых логинов" );
    }
    @Override
    public void run() {
        try {
            System.out.println ("Колличество клиентов run = " + clients.size () );
            while (connection.isConnected ()) {
                messages = (String) input.readObject();
                historyMassages.append (messages);
                if (historyMassages.length ( ) > 5000)
                    historyMassages.delete (5000, historyMassages.length ( ));
                synchronized (clients) {
                    for (ConnectedClient empty : Server.clients) {
                        empty.output.writeObject (historyMassages.toString ( ));
                    }
                }
            }
        } catch (IOException e) {
        } catch (ClassNotFoundException e) {
        } finally {
            clients.remove (nameClient);
            System.out.println ("Пользователь отключился");
            System.out.println ("Количество клиентов = " + clients.size () );
        }
    }
}
READ ALSO
how does a ball object draw itself onto a panel in a different class? [требует правки]

how does a ball object draw itself onto a panel in a different class? [требует правки]

Как объект шара нарисовывается на панели в другом классе?

334
Эффективные ли побитовые операции в Java?

Эффективные ли побитовые операции в Java?

Всем привет, Возник вопрос по битовым операциям в JavaЕсли брать нативные языки на подобие "с++" или "С" то там понятен выиграш в производительности...

315
Как сделать Parallax анимацию

Как сделать Parallax анимацию

Хочу сделать анимацию вроде той, какая на гифке внизу, но не для ViewPager-а, а для замещения одного View другим

215
обозначение многоугольника [требует правки]

обозначение многоугольника [требует правки]

Как Java обозначает многоугольник?

361