Russian Qt Forum
Ноябрь 22, 2024, 19:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Потоки и большие объемы информации....  (Прочитано 3807 раз)
AntonUfo
Гость
« : Январь 27, 2011, 00:52 »

Есть две программы  клиент - сервер  , сервер многопоточный ( в момент подсоединения i-го клиента создается поток в котором выполняются огромные вычисления). Периодически созданный поток отправляет большую "порцию" данных клиенту. Клиент получив порцию данных так же проводит некие вычисления которые так же могут занимать много времени....

Вопрос, должен ли клиент "оповещать" сервер что он расчеты закончил и может обработать новую порцию данных...
а, сервер выполнять расчеты только в том случае если клиент отработал порцию данных и готов обрабатывать следующую....

Прием данных и на клиенте и на сервере

Код:


    QDataStream in(&tcpSocket);
    in.setVersion(QDataStream::Qt_4_4);

forever {

        if (nextBlockSize == 0) {
            if (tcpSocket.bytesAvailable() < sizeof(quint16))
                break;
            in >> nextBlockSize;
        }

        if (nextBlockSize == 0xFFFF) {
connectUp = false;
            closeConnection();
            break;
        }

        if (tcpSocket.bytesAvailable() < nextBlockSize)
            break;

in >> порция данных;


что будет если сервер передаст клиенту новую порцию данных а клиент еще старую не обработал..... ?
у tcpSocket есть какой либо буфер ?
Записан
Denjs
Гость
« Ответ #1 : Январь 27, 2011, 01:16 »

ничо не скажу про основную проблему - это скорее ваш личный гемор с проектированием сетевых протоколов взаимодействия, которую вы не хотите (по моему) решать.

Но у QTcpSocket  входной буфер есть. Иначе бы bytesAvalable() не существовал.

____________________________________
Т.е. вы используете протокол транспортного уровня (соединение tcp|ip) скажем так "в сыром виде", "без логики"; а вам похоже, нужен протокол более высокого уровня - включающий не только данные но и какие-то "сигнальные извещения". реализовывать этот протокол вам придется самому - т.е. вы сами, анализируя данные передаваемые по каналу связи, должны понимать - данные там или какие-то "сигналы" ( запросы-ответы и прочее).

Но можно и немного проще - организуйте второе соединение, на другом порту для того что бы держать руку на пульсе - и через это соединение обменивайтесь запрос-ответами о том кто что посчитал или другое. что бы не смешивать данные и сигналы в одном потоке.

« Последнее редактирование: Январь 27, 2011, 01:21 от Denjs » Записан
AntonUfo
Гость
« Ответ #2 : Январь 27, 2011, 10:20 »

ничо не скажу про основную проблему....

спасибо большое за вторую часть ответа, по первой части.... вы не правы... я не знаю как правильно решить... какой должен быть подход.... ну собственно во второй части вы его мне и обрисовали... если я правильно понял то между клиентом - сервером должно быть налажено взаимодействие (готов к работе -  занят, для обоих)..
дело в том что многопоточное и сетевое взаимодействие и в ассистенте и в книгах описано довольно приметивно... включились передали отключились... или запустили поток передаем данные... а вот о том как организовать взаимодействие посложнее ничего путного...., вот и получается что по факту и почитать посмотреть нечего....

ЗЫ: Про буфер спрашивал т.к. если "порции" данных не очень большие и обрабатываются быстро то все ок. все все успевают, но как только объем данных повышается то часть данных обрабатывается а часть такое впечатление что просто не приходит...
А каков размер буфера ?

PSS: По поводу

Цитировать
..ваш личный гемор с проектированием сетевых протоколов взаимодействия, которую вы не хотите (по моему) решать

..заметьте , я не спрашивал как мне написать программу, я спрашивал какой должен быть подход в общем виде...
« Последнее редактирование: Январь 27, 2011, 10:27 от AntonUfo » Записан
Странник
Гость
« Ответ #3 : Январь 27, 2011, 12:08 »

ЗЫ: Про буфер спрашивал т.к. если "порции" данных не очень большие и обрабатываются быстро то все ок. все все успевают, но как только объем данных повышается то часть данных обрабатывается а часть такое впечатление что просто не приходит...
А каков размер буфера ?
размер буфера чтения QTcpSocket можно изменить с помощью setReadBufferSize(). но если интересует надежное решение, то, конечно, необходимо использовать оповещения.
Записан
Denjs
Гость
« Ответ #4 : Январь 27, 2011, 13:41 »

дело в том что многопоточное и сетевое взаимодействие и в ассистенте и в книгах описано довольно приметивно... включились передали отключились... или запустили поток передаем данные... а вот о том как организовать взаимодействие посложнее ничего путного...., вот и получается что по факту и почитать посмотреть нечего....
Извините ежели задел) не ставил цели вас обидеть)

ладно. По попду примитивности - ну да) - задача демок - продемонстрировать работу компонент для сети. Каждая компонента работает на каком-либо одном уровне модели OSI. Вам демонстрируют работу компонент какого либо уровня (например "транспортный" - если это QTcpSocket). Задача данного уровня - подключиться, передать данные, сигнализировать об ошибке "если что" и отключиться. Взаимодействие на более высоком уровне - т.е. создание компонент реализующих протокол более высокого уровня, поддерживающих ваш протокол уровня "сеанс" или "представление" вы должны взять на себя сами. Т.е. предполагается, что если вы знаете то как протоколы более высокого уровня подддерживаются протоколами более низкого уровня - то создание такого протокола для вас не должно составить труда.

Как вариант я могу предложить вам классику жанра - escape-последовательности. Для удобства дополним их "экранирующим символом".
т.е. все что идет после esc-символа рассматривается как код команды или сообщения, только если esc-символ не "закрыт" экранирующим символом, который сам по себе не обрабатывается, а только говорит что следающий за ним символ надо рассматривать как "данные". для передачи экранирующего символа - его надо сам экранировать.

Таким образом у вас будет класс который может принимает на входе данные и управляющие команды - "экранирует их и прочее" - а на выходе - поток символов который вы передаете по сети (тут мы имеем в виду, что вы передаете их на транспортный уровень - объекту QTcpSocket). На другом конце копия вашего класса проводит анализ данных полученных от транспортного уровня, выделяет из них ескейпы и экранирующие символы, и выводит либо поток данных, или генерирует сигналы о получении управляющих сообщений.

по моему для ваших целей вполне хватит.
« Последнее редактирование: Январь 27, 2011, 14:38 от Denjs » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.056 секунд. Запросов: 20.