Запись сокета Java-клиента пропускается, если сервер не читает - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть Java-программа, в которой клиент будет непрерывно отправлять число на сервер, снова и снова, используя сокеты. Обычно вызовы readObject или writeObject ожидают, пока другая сторона не будет готова к отправке или получению. Но в моем конкретном случае клиент просто пропустит запись на сервер, если сервер в данный момент не читает.

Ниже мой код клиента. У меня есть класс Request для отправки информации, в моем случае это просто целое число:

    Socket socket = new Socket("localhost", 2910);
    ObjectOutputStream outToServer = new ObjectOutputStream(socket.getOutputStream());
    Random r = new Random();
    while(true) {
        Request request = new Request();
        request.reqType = Request.TYPE.ADD;
        request.add = r.nextInt(100);
        System.out.println("Sending to server: " + request.add);
        outToServer.writeObject(request);
        Thread.sleep(100);
    }

А вот серверная часть:

try {
        ObjectInputStream inFromClient = new ObjectInputStream(socket.getInputStream());
        ObjectOutputStream outToClient = new ObjectOutputStream(socket.getOutputStream());

        while(true) {
            Request req = (Request)inFromClient.readObject();

            switch (req.reqType) {
                case ADD : {
                    Logger.getInstance().log(name + " added " + req.add);
                    serv.add(req.add);
                    break;
                }
                case RESULT : {
                    Logger.getInstance().log(name + " produced result " + req.result);
                    break;
                }
                case RETRIEVE : {
                    int[] retrieve = serv.retrieve();
                    Logger.getInstance().log(name + " retrieved: " + retrieve[0] + ", " + retrieve[1] + ", " + retrieve[2]);
                    outToClient.writeObject(new Request(retrieve));
                    break;
                }
            }

        }
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }

Приведенный выше код запускается в потоке. Итак, дело в том, что мой клиент отправил объект Request и установил тип ADD. Сервер прочитает / примет запрос, проверит его тип и обнаружит, что это ADD, поэтому он будет вызывать serv.add. Этот вызов может вызвать вызов "wait ()", что означает, что поток здесь приостановлен в этой точке и, таким образом, застрял. Клиент попытается отправить следующий объект запроса, но поскольку поток сервера застрял в вызове serv.add, клиент, похоже, ничего не пишет, просто пропускает вызов и выполняет цикл while снова. Поэтому я пытаюсь отправить несколько запросов, которые сервер не получает.

Надеюсь, это имеет смысл.

Так что я думаю, мой вопрос: Если сервер в настоящее время не пытается читать с клиента, а клиент пытается записать, вызовет ли `writeObject 'истечение времени ожидания, а затем просто продолжится, или что происходит?

1 Ответ

0 голосов
/ 01 ноября 2018

Так что для дальнейшего использования. WriteObject просто отправит кучу объектов на сервер. ReadObject будет читать их в своем темпе. Кажется, существует некоторый внутренний буфер по отношению к readObject. Мой клиент отправляет 30 целых чисел, сервер читает 10, а затем wait (). Клиент завершается. Сервер в какой-то момент продолжит работу, а затем прочитает остальные отправленные объекты. Так что я ничего не теряю.

...