Здравствуйте, Макс!
На стр. 561 приведен листинг 39.6. Не могу найти в справке Qt информацию по методу write(), который используется в последней строке метода sendToClient(), а именно: “pSocket->write(arrBlock);”. Я так понял, метод write() сокета принимает данные с quint16 вначале? Т.е. без этого числа вначале сокет “не поймет” что ему передается? Если можно, проясните этот момент подробнее…
На странице 566 в листинге 39.12 (метод slotSentToServer()) есть строчка “out << quint16(arrBlock.size() – sizeof(quint16));", если написать "out << quint(0);" всё также работает (сообщения любой длины приходят полностью… Подобный слот есть и в коде сервера. В общем создается впечатление, что неважно какое число отправлять "в сокет", всё и так хорошо работает… Помогите, пожалуйста, разобраться с этим вопросом. И прокомментируйте использование цикла for(;;) в листинге 39.10 на стр. 565, с трудом понимаю зачем он там нужен… Спасибо!
Здравствуйте, Вячеслав!
Листинг 39.12 я подробно не комментировал, а сослался 39.6, потому что он очень похож на него. Посмотрите пожалуйста описание листинга 39.6 и если он будет не понятно, тогда попробуем разобрать эти листинги в этой ветке.
Уважаемый Макс!
Я конечно же смотрел Листинг 39.6, т.к. изучаю книгу по порядку, от главы к главе. Мне непонятен код этих методов, а именно зачем нужна строчка:
out << quint16(arrBlock.size() – sizeof(quint16));
Что "происходит" в этих методах я понимаю, не понимаю зачем сделано именно так? Если написать "out << quint(0);" то все пакеты так же приходят удаленной машине. Зачем вычислять размер переданной информации?
Здравствуйте, Вячеслав!
Для того чтобы убедится в необходимости указания размера блока, закоментируйте в листингах следующие строчки:
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)). И помещаем измененную дайтаграмму в сокет.
Спасибо за развернутый ответ, Макс!
Я закомментировал и в коде сервера и в коде клиента данные строчки, отправил большое сообщение (максимально отправлял 18734 символа) сообщение сервер получает полностью…
И по поводу цикла for(;;) в листинге 39.10. Подскажите, пожалуйста, в каком случае не все данные могут одновременно прийти по сети клиенту (или серверу)? И интересуют следующие строки кода в листингах 39.5 и 39.10:
…
// Это условие нужно для того, чтобы проверить не меньше ли пришедший блок типа quint16
// Т.е., если я правильно понял, один блок принимаемый сокетом должен быть размером quint16
// и больше, именно для этого нужно это условие?
if (pClientSocket->bytesAvailable() > m_nNextBlockSize;
…
// Это условие нужно для того, чтобы проверить есть ли еще что-то, что “хочет” прийти на сокет?
if (pClientSocket->bytesAvailable() < m_nNextBlockSize) {
break;
}
…
Макс, объясните, пожалуйста, правильны ли мои умозаключения в комментариях выше. И дайте свое пояснение, пожалуйста!
P.S.: очень не хватает подобных комментариев в листингах…
“Это условие нужно для того, чтобы проверить не меньше ли пришедший блок типа quint16”
> Да, потому что если размер блока меньше 2 байт, то это ознчает что датаграммы нет.
“Т.е., если я правильно понял, один блок принимаемый сокетом должен быть размером quint16 и больше, именно для этого нужно это условие?”
> Именно так. Принимаемый блок должен быть размером больше 2 байт. 2 Байта содержат в себе только информацию о размере блока.
Здравствуйте! Как мне кажется, при реализации программы UDP-клиента и UDP-сервера Вы перепутали их роли: сервером должна быть та программа, которая “слушает” на порту приходящие сообщения т.е. та, которая вызывает метод bind(); а та программа, которая шлёт сообщения на заранее известный адрес:порт должна быть клиентом.
Здравствуйте!
Не могли бы Вы объяснить зачем в листинге 39.9 (564 стр) в третьем и пятом соединениях сигналов со слотами используется третий параметр this? Ведь в остальных вызовах connect этот параметр опущен в связи с тем, что соединение происходит в классе получателе. Спасибо!
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish.AcceptRead More
Privacy & Cookies Policy
Privacy Overview
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
На стр. 560 опечатка в предложении: “При поступлении запросов от клиентов отправляется сигнал readyToRead(), …”, правильно – “readyRead()”.
Да, это опечатка. Правильно будет “сигнал readyRead()”. Спасибо
Здравствуйте, Макс!
На стр. 561 приведен листинг 39.6. Не могу найти в справке Qt информацию по методу write(), который используется в последней строке метода sendToClient(), а именно: “pSocket->write(arrBlock);”. Я так понял, метод write() сокета принимает данные с quint16 вначале? Т.е. без этого числа вначале сокет “не поймет” что ему передается? Если можно, проясните этот момент подробнее…
Здравствуйте, Вячеслав!
Информацию по методу write() нужно искать описании класса QIODevice, так как класс QTcpSocket наследует метод от него.
На странице 566 в листинге 39.12 (метод slotSentToServer()) есть строчка “out << quint16(arrBlock.size() – sizeof(quint16));", если написать "out << quint(0);" всё также работает (сообщения любой длины приходят полностью… Подобный слот есть и в коде сервера. В общем создается впечатление, что неважно какое число отправлять "в сокет", всё и так хорошо работает… Помогите, пожалуйста, разобраться с этим вопросом. И прокомментируйте использование цикла for(;;) в листинге 39.10 на стр. 565, с трудом понимаю зачем он там нужен… Спасибо!
Здравствуйте, Вячеслав!
Листинг 39.12 я подробно не комментировал, а сослался 39.6, потому что он очень похож на него. Посмотрите пожалуйста описание листинга 39.6 и если он будет не понятно, тогда попробуем разобрать эти листинги в этой ветке.
Уважаемый Макс!
Я конечно же смотрел Листинг 39.6, т.к. изучаю книгу по порядку, от главы к главе. Мне непонятен код этих методов, а именно зачем нужна строчка:
out << quint16(arrBlock.size() – sizeof(quint16));
Что "происходит" в этих методах я понимаю, не понимаю зачем сделано именно так? Если написать "out << quint(0);" то все пакеты так же приходят удаленной машине. Зачем вычислять размер переданной информации?
Здравствуйте, Вячеслав!
Для того чтобы убедится в необходимости указания размера блока, закоментируйте в листингах следующие строчки:
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)). И помещаем измененную дайтаграмму в сокет.
Спасибо за развернутый ответ, Макс!
Я закомментировал и в коде сервера и в коде клиента данные строчки, отправил большое сообщение (максимально отправлял 18734 символа) сообщение сервер получает полностью…
И по поводу цикла for(;;) в листинге 39.10. Подскажите, пожалуйста, в каком случае не все данные могут одновременно прийти по сети клиенту (или серверу)? И интересуют следующие строки кода в листингах 39.5 и 39.10:
…
// Это условие нужно для того, чтобы проверить не меньше ли пришедший блок типа quint16
// Т.е., если я правильно понял, один блок принимаемый сокетом должен быть размером quint16
// и больше, именно для этого нужно это условие?
if (pClientSocket->bytesAvailable() > m_nNextBlockSize;
…
// Это условие нужно для того, чтобы проверить есть ли еще что-то, что “хочет” прийти на сокет?
if (pClientSocket->bytesAvailable() < m_nNextBlockSize) {
break;
}
…
Макс, объясните, пожалуйста, правильны ли мои умозаключения в комментариях выше. И дайте свое пояснение, пожалуйста!
P.S.: очень не хватает подобных комментариев в листингах…
“Это условие нужно для того, чтобы проверить не меньше ли пришедший блок типа quint16”
> Да, потому что если размер блока меньше 2 байт, то это ознчает что датаграммы нет.
“Т.е., если я правильно понял, один блок принимаемый сокетом должен быть размером quint16 и больше, именно для этого нужно это условие?”
> Именно так. Принимаемый блок должен быть размером больше 2 байт. 2 Байта содержат в себе только информацию о размере блока.
Здравствуйте! Как мне кажется, при реализации программы UDP-клиента и UDP-сервера Вы перепутали их роли: сервером должна быть та программа, которая “слушает” на порту приходящие сообщения т.е. та, которая вызывает метод bind(); а та программа, которая шлёт сообщения на заранее известный адрес:порт должна быть клиентом.
Здравствуйте!
Не могли бы Вы объяснить зачем в листинге 39.9 (564 стр) в третьем и пятом соединениях сигналов со слотами используется третий параметр this? Ведь в остальных вызовах connect этот параметр опущен в связи с тем, что соединение происходит в классе получателе. Спасибо!