Глава 39 – Программирование поддержки сети

Программирование поддержки сети

Приобрести книгу можно на сайте ozon.ru и в электронном виде на Google Play:
Приобрести книгу о Qt и C++ на Ozon.ru Купить книгу о Qt и C++ на Goole Play

12 thoughts on “Глава 39 – Программирование поддержки сети

  1. На стр. 560 опечатка в предложении: “При поступлении запросов от клиентов отправляется сигнал readyToRead(), …”, правильно – “readyRead()”.

  2. Здравствуйте, Макс!
    На стр. 561 приведен листинг 39.6. Не могу найти в справке Qt информацию по методу write(), который используется в последней строке метода sendToClient(), а именно: “pSocket->write(arrBlock);”. Я так понял, метод write() сокета принимает данные с quint16 вначале? Т.е. без этого числа вначале сокет “не поймет” что ему передается? Если можно, проясните этот момент подробнее…

    1. Здравствуйте, Вячеслав!
      Информацию по методу write() нужно искать описании класса QIODevice, так как класс QTcpSocket наследует метод от него.

  3. На странице 566 в листинге 39.12 (метод slotSentToServer()) есть строчка “out << quint16(arrBlock.size() – sizeof(quint16));", если написать "out << quint(0);" всё также работает (сообщения любой длины приходят полностью… Подобный слот есть и в коде сервера. В общем создается впечатление, что неважно какое число отправлять "в сокет", всё и так хорошо работает… Помогите, пожалуйста, разобраться с этим вопросом. И прокомментируйте использование цикла for(;;) в листинге 39.10 на стр. 565, с трудом понимаю зачем он там нужен… Спасибо!

    1. Здравствуйте, Вячеслав!
      Листинг 39.12 я подробно не комментировал, а сослался 39.6, потому что он очень похож на него. Посмотрите пожалуйста описание листинга 39.6 и если он будет не понятно, тогда попробуем разобрать эти листинги в этой ветке.

      1. Уважаемый Макс!
        Я конечно же смотрел Листинг 39.6, т.к. изучаю книгу по порядку, от главы к главе. Мне непонятен код этих методов, а именно зачем нужна строчка:
        out << quint16(arrBlock.size() – sizeof(quint16));
        Что "происходит" в этих методах я понимаю, не понимаю зачем сделано именно так? Если написать "out << quint(0);" то все пакеты так же приходят удаленной машине. Зачем вычислять размер переданной информации?

        1. Здравствуйте, Вячеслав!
          Для того чтобы убедится в необходимости указания размера блока, закоментируйте в листингах следующие строчки:
          out.device()->seek(0);
          out << quint16(arrBlock.size() – sizeof(quint16));
          Теперь отправьте из клиента сообщение побольше, например 512 символов. Посмотрите, что получит сервер.

          Постараюсь более подробно пояснить, непонятные моменты.
          В листингах 39.6 и 39.10 в качестве первых двух байтов (quint16) датаграммы мы передаем размер блока. Вначале мы вписываем в это поле значение 0 (строчка out << quint16(0)). Затем после того как датаграмма сформировалась “перетираем” значание 0, в поле размера блока, его настоящим размером (строчки с <seek(0)), для этого от размера сформированного блока нужно отнять размер 2 байт, тоесть (строчка arrBlock.size() – sizeof(quint16)). И помещаем измененную дайтаграмму в сокет.

          1. Спасибо за развернутый ответ, Макс!
            Я закомментировал и в коде сервера и в коде клиента данные строчки, отправил большое сообщение (максимально отправлял 18734 символа) сообщение сервер получает полностью…

      2. И по поводу цикла for(;;) в листинге 39.10. Подскажите, пожалуйста, в каком случае не все данные могут одновременно прийти по сети клиенту (или серверу)? И интересуют следующие строки кода в листингах 39.5 и 39.10:

        // Это условие нужно для того, чтобы проверить не меньше ли пришедший блок типа quint16
        // Т.е., если я правильно понял, один блок принимаемый сокетом должен быть размером quint16
        // и больше, именно для этого нужно это условие?

        if (pClientSocket->bytesAvailable() > m_nNextBlockSize;

        // Это условие нужно для того, чтобы проверить есть ли еще что-то, что “хочет” прийти на сокет?

        if (pClientSocket->bytesAvailable() < m_nNextBlockSize) {
        break;
        }

        Макс, объясните, пожалуйста, правильны ли мои умозаключения в комментариях выше. И дайте свое пояснение, пожалуйста!
        P.S.: очень не хватает подобных комментариев в листингах…

        1. “Это условие нужно для того, чтобы проверить не меньше ли пришедший блок типа quint16”
          > Да, потому что если размер блока меньше 2 байт, то это ознчает что датаграммы нет.

          “Т.е., если я правильно понял, один блок принимаемый сокетом должен быть размером quint16 и больше, именно для этого нужно это условие?”
          > Именно так. Принимаемый блок должен быть размером больше 2 байт. 2 Байта содержат в себе только информацию о размере блока.

  4. Здравствуйте! Как мне кажется, при реализации программы UDP-клиента и UDP-сервера Вы перепутали их роли: сервером должна быть та программа, которая “слушает” на порту приходящие сообщения т.е. та, которая вызывает метод bind(); а та программа, которая шлёт сообщения на заранее известный адрес:порт должна быть клиентом.

Leave a Reply to Вячеслав Турчин Cancel reply

Your email address will not be published.

Please reload

Please Wait