Название: вопрос по qtcpsocket Отправлено: koldun90 от Февраль 07, 2018, 21:38 здравствуйте есть сервер основанный на qtcpserver и клиент на qtcpsocket
сервер посылает сообщение клиенту в цикле ввида Код
собственно клиент принимает сообщение в слоте связанном с сигналом readyread прием данных от сервака Код
соответственно в консоль выводится сообщение Те срабатывает два сигнала ready read 012345678910111213141516 17181920212223242526272829 Но вот в чем вопрос можно ли сделать так чтобы сервер отсылал данные (сделал 1 write) а на клиенте сработал readyread и он получил то что я ему послал за одну итерацию цикла ( в данном примере одно чило из 30) просто на скока я понимаю write асинхронный он пишет сначало в свой внутренний буфер, а потом когда решит выплевывает клиенту если делаю так Код то все тоже самое Вообщем как-то можно организовать полностью синхронную отправку данных? Название: Re: вопрос по qtcpsocket Отправлено: koldun90 от Февраль 07, 2018, 22:53 Код
В принципе можно сделать задержу 8000 микросекунд =0,008 секунды с помощью usleep но проблема в больших данных Пример в данном случае на числах а я буду отсылать содержимое папок Те допустим в папке /usr/bin содержится много файлов у меня порядка 1700 и мне нужно отослать все файлы в этой папке какие есть клиенту чтобы он у себя их отобразил в QTreeVidget и каждый write у меня будет имя файла Название: Re: вопрос по qtcpsocket Отправлено: ssoft от Февраль 08, 2018, 08:06 Вообщем как-то можно организовать полностью синхронную отправку данных? Если поднапрячься можно, путем настройки сокетов, паузами или любыми другими костылями), которые сломаются в самый неподходящий момент. Но вопрос ЗАЧЕМ? Асинхронный write/read организуют максимально эффективный способ передачи данных. Любая синхронизация - снижение производительности (причем на порядки величин), дополнительные ограничения и т.п. Пакеты данных могут склеиваться или напротив приходить не полностью, а частями. Их в любом случае нужно обрабатывать по мере прихода данных - отделять друг от друга или склеивать в соответствии с реализуемым протоколом обмена. Никто не гарантирует, что даже int придет полностью за 1 readyRead(). Поэтому имеется возможность узнать сколько байт пришло с помощью bytesAvailable() и производить считывание только при их достаточном количестве. Название: Re: вопрос по qtcpsocket Отправлено: koldun90 от Февраль 08, 2018, 17:31 Я вас понял. Но как мне лучше организовать все это дело.
Смысл в том что я отсылаю команду серверу с параметром имя папки. Сервер получает данную команду. Он должен мне переслать имена файлов и папок в заданном каталоге(допустим каталог /usr/bin). Я получаю содержимое там порядка 1700 объектов) 1700 фалов грубо говоря каждый файл имеет длину 5 байт. В итоге мне нужно будет переслать порядка 20000 байт. Я так понял вы предлагаете мне сделать Один qtcpsocket::write. В котором я сразу пошлю порядка 20000 байт? Те я с сервака посылаю 20000 байт. А на клинте я тупо жду когда мне все эти байты придут и только потом когда получу все 20000 байт далее уже двигаться по коду... Название: Re: вопрос по qtcpsocket Отправлено: koldun90 от Февраль 09, 2018, 08:36 Как в примере qt. Client fortune example.
Я так понял что в начале нужно послать размер затем Затем ждать чтоб весь пакет поступил в сокет . И только потом его прочитать. Название: Re: вопрос по qtcpsocket Отправлено: ssoft от Февраль 09, 2018, 08:41 Я так понял вы предлагаете мне сделать Один qtcpsocket::write. В котором я сразу пошлю порядка 20000 байт? Нет, я не это имел ввиду). Как вам отправлять данные вы сами решите, по одному имени или все сразу. Вы хотите организовать клиент серверное взаимодействие, которое реализуется посредством какого-то прикладного протокола. Протокол обмена подразумевает, что данные передаются пакетами, а не непрерывно. Пакет данных имеет какой-то формат - как минимум количество байт и внутреннее содержимое. Из сокета вычитываются пакеты данных, а уже потом интерпретируется их содержимое. На стороне отправителя: * сериализуем сообщение/команду в пакет (например, QByteArray). * пакет отправляется в сокет - в виде {размер, содержимое} На стороне получателя: * ожидаем, когда в сокете будет достаточно байт для чтения размера пакета * вычитываем размер пакета * ожидаем, когда в сокете будет достаточно байт для чтения содержимого пакета * вычитываем содержимое пакета * десериализуем сообщение/команду из пакета * обрабатываем сообщение/команду. Название: Re: вопрос по qtcpsocket Отправлено: koldun90 от Февраль 09, 2018, 09:56 Это понятно что структура пакета у меня будет (размер+данные).
Вся проблема в том что если я в цикле посылаю 1500 Пакетов(делаю write) то мне же известен размер одного посылаемого пакета. Далее я прочитал размер пакета(packsize) Далее я жду пока поступят данные пакета затем учитывают их по вся проблема в то что пакеты склеиваются друг с другом и как их обрабатывать непонятно Название: Re: вопрос по qtcpsocket Отправлено: ssoft от Февраль 09, 2018, 10:54 Псевдокод
Код
Название: Re: вопрос по qtcpsocket Отправлено: koldun90 от Февраль 09, 2018, 11:43 У вас packet_byte_count это размер одного пакета посылаемых write или это я как бы должен посчитать при отправке с сервера предварительно размер всех пакетов. Ведь я буду делать write в цикле for
Название: Re: вопрос по qtcpsocket Отправлено: koldun90 от Февраль 09, 2018, 11:47 Код Я не использую qdatastream. Можно мне условие в цикле заменить? Название: Re: вопрос по qtcpsocket Отправлено: ssoft от Февраль 09, 2018, 12:29 Для каждого пакета вначале вычитывается packet_byte_count - это размер пакета (для каждого пакета свой). Если пакет вычитан, то packet_byte_count обнуляется, если нет - packet_byte_count содержит необходимое количество байт для считывания пакета.
Если не используется QDataStream, то код (с поправками) может выглядеть так Код
|