Клиент зависает при чтении объекта из сокета

1

Я разрабатываю простое приложение Client-Server поверх сокета, но я не могу понять, почему клиент зависает, когда он читает объект. Сервер должен иметь возможность работать с несколькими клиентами.

Сохраняя это просто, мой Сервер выглядит так:

    ...
    server_thread = new Thread(new Runnable() {
        @Override
        public void run() {
            int p = 0;
            ObjectInputStream in;
            ObjectOutputStream out;
            NetworkOffer message;    

            try (ServerSocket serverSocket = new ServerSocket(port)) {
                // get connections
                LinkedList<Socket> client_sockets = new LinkedList<>();
                while (p++ < partecipants) client_sockets.add(serverSocket.accept());

                // sending welcome object
                for (Socket socket : client_sockets) {
                    out = new ObjectOutputStream(socket.getOutputStream());
                    message = new NetworkOffer();
                    out.writeObject(buyer_offer);
                }
            ...

Мой клиент:

    ...
    client_thread = new Thread(new Runnable() {

        @Override
        public void run() {
            ObjectInputStream in;
            NetworkOffer smessage;
            try {
                Socket ssocket = new Socket("localhost", port);
                in = new ObjectInputStream(ssocket.getInputStream());

                // waiting server message
  ------------->Object o = in.readObject();
                smessage = (NetworkOffer)o;


                System.out.println(smessage.toString());
                ...

EDIT: Чтобы сделать все более ясным, это протокол, который я хочу реализовать:

  1. N клиентов подключаются к серверу
  2. Сервер отправляет welcome клиентам

  3. Каждый клиент делает предложение

  4. Сервер выбирает лучшее предложение и отправляет каждому клиенту сообщение с Accept/Reject
  5. Если нет приемлемого предложения goto 3.

Клиент Object o = in.readObject(); даже если сервер уже отправил свое сообщение. Нет ошибки, ничего. Тема просто замораживается там, ожидая чего-то.

Что происходит?

Теги:
sockets

2 ответа

1

Как я уже говорил, вы уверены, что сервер отправил данные клиенту - нет флеш-буфера, поэтому он все еще может кэшироваться.
out.flush() будет следить за тем, чтобы буфер был сброшен. Будет иметь смысл обрабатывать клиентов отдельно и отправлять им периодические сообщения, чтобы обновить их о статусе.
Полезно, чтобы код вашего сервера обрабатывал также отключение соединения/соединения клиента.

На стороне примечание:

message = new NetworkOffer();
out.writeObject(buyer_offer);

Ваш код, кажется, отправляет что-то еще, чего нет в вашем примере. Это верно?

1

Проблема заключается в том, что ServerSocket.accept() - это блокирующий вызов, означающий, что сервер будет зависать, пока кто-то не подключится к нему. Когда кто-то подключится, сервер добавит этот новый сокет в client_sockets. Если количество добавленных сокетов меньше participants, оно снова вызовет accept() и ждет другого соединения. Он будет вводить только ваш цикл for если общее количество сокетов равно participants. Вам нужно создать новый поток для обработки каждого входящего клиентского сокета и разрешить серверу немедленно вернуться к ServerSocket.accept(). Взгляните на шаблон Reactor для хорошего примера того, как это реализовать.

Как выглядит ваш код:

  1. Сервер ждет соединений.
  2. Когда клиент подключается, создайте новый поток для обработки соединения.
  3. Сервер возвращается в ожидании соединений.
  4. Новая цепочка отправляет приветственное сообщение на сокет, добавляет сокет в список client_sockets и ждет предложений клиентов.
  5. Храните предложения клиентов.
  6. Когда все предложения были получены, сравните, чтобы найти лучшее.
  7. Отправлять Accept/Reject сообщений.
  • 0
    Я не хочу создавать поток для каждого клиента, потому что они должны ждать других, поэтому я думаю, что все в порядке, что accept() является блокирующим вызовом. Что я не могу понять, так это: все клиенты подключаются: хорошо. Затем сервер отправляет первый «добро пожаловать»; на этом этапе один поток клиента не должен быть освобожден и продолжать? Вместо этого все клиенты заблокированы в in.readObject(); , Почему это происходит?
  • 0
    @ marka.thore Дело в том, что сервер не отправляет приветственное сообщение, пока все клиенты не подключились. Они ждут там, потому что сервер ничего не отправил.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню