Russian Qt Forum

Qt => Работа с сетью => Тема начата: AlphaGh0St от Январь 29, 2016, 17:12



Название: readAll() и фрагментация
Отправлено: AlphaGh0St от Январь 29, 2016, 17:12
Всем привет!
Отправляю по сети, из одной программы, структуру размером в 320 байт, затем отправляю ещё данные.
В принимающей программе по сигналу readyRead, в слоте вызываю readAll().

По идее слот на readyRead должен был вызваться дважды. В первый раз должна была быть принята структура, размером в 320 байт. А вторым вызовом приняты остальные данные.

А на деле, слот на readyRead вызывается один раз и метод readAll() возвращает все данные сразу: и структуру и остальные данные.
Складывается впечатление, что на уровне ОС или Qt происходит фрагментация данных, идущих из сети.

Подскажите, что можно сделать, чтобы принимать данные раздельно, т.е. без фрагментации?
Отправили структуру - приняли структуру.
Отправили остальные данные - приняли остальные данные.

Благодарю.


Название: Re: readAll() и фрагментация
Отправлено: Old от Январь 29, 2016, 17:16
Не стоит этого делать. Нужно нормально разбирать принятые данные.
Читайте про алгоритм Nagle, там все объясняется.


Название: Re: readAll() и фрагментация
Отправлено: AlphaGh0St от Январь 29, 2016, 17:28
Как раз наткнулся на алгоритм Nagle при внимательном чтении документации по сокетам.
Спасибо за совет.


Название: Re: readAll() и фрагментация
Отправлено: Igors от Январь 30, 2016, 08:47
Подскажите, что можно сделать, чтобы принимать данные раздельно, т.е. без фрагментации?
Отправили структуру - приняли структуру.
Отправили остальные данные - приняли остальные данные.
Сетью занимаюсь раз в неск лет, ни о каких алгоритмах не слыхал. Тем не менее берусь утверждать: такой задачи лучше не ставить. Всегда можно посмотреть сколько байт пришло, если этот число меньше размера заголовка - ничего не делать. Как только весь заголовок пришел - считали его, разобрали и получили из него размер данных. И начинаете сливать данные до упора


Название: Re: readAll() и фрагментация
Отправлено: Bepec от Январь 30, 2016, 09:26
Алгоритм Нейгла по сути это буфер для малых сообщений. Он не везде подойдёт, особенно там где требуется нормальный отклик.

На вашем месте я бы прислушался к Igors, принимаете данные, разбиваете по заголовкам и парсите.


Название: Re: readAll() и фрагментация
Отправлено: Old от Январь 30, 2016, 09:43
На вашем месте я бы прислушался к Igors, принимаете данные, разбиваете по заголовкам и парсите.
А чем совет Igors отличается от моего?  ;D
Я посоветовал почитать про алгоритм Нагла, потому что он объясняет поведение сетевого стека, что даст ТС понимание для чего это делается.
Но можно ничего не читать, а сделать как кажется. :)
Ну и не во всех протоколах есть те самые чудо заголовки.