Название: QTcpSocket QTcpServer скорости. Отправлено: Orfus от Июль 21, 2011, 13:44 Доброго дня. Стоит необходимость передавать файлы внутри локальной сети (100Мбит/сек). Файлы передаются, вопрос только в скорости передачи.
Весь алгоритм отправки. 1) Подключился к клиенту. 2) Выбрал файл отправки. 3) Кинул имя файла и его размер. 4) Дождался ответа, что имя и размер приняты и клиент ждёт "начинку". Высылает начинку. Ниже кусок непосредственно высылающий файл. Код 5) Дождался сообщения что файл принят и просчитал среднюю скорость передачи. Алгорит приёма. 1) Приём подключения от сервера. QTcpServer стоит на стороне клиента ;D 2) Приём имени файла и его размера. 3) Приём содержимого файла. Код 4) Считает среднюю скорость передачи и высылает подтверждение приёма. 5) ждёт следующую шапку файла. Далее имеется несколько машин: A - 3ггц, 1 гиг оперативки, 1Гигабит сетевая, WinXp B - 2.6ггц, 768 мб оперативки, 100Мегабит ,WinXp C - 3.2ггц, 1 гиг оперативки, 100Мегабит, Vista Собственно говоря проблема в следующем: имеется тестовый файл размером в 50МегаБайт который я перекидываю: с А->A скорость 250+мегабит c A->B ~50мегабит с А->C ~8мегабит c B->B ~50мегабит c С->C ~50 мегабит c B->A ~50 мегабит Я понимаю что выше 100мегабит скорость не получить, но вот почему она в определенных случаях такая маленькая понять не могу. Подскажите в какую сторону смотреть? Возможно нужно какие-то настройки сокетов через Api править? Я не вижу как ещё можно ускорить алгоритм отправки и приёма. Название: Re: QTcpSocket QTcpServer скорости. Отправлено: LisandreL от Июль 21, 2011, 14:41 _blockSize чему равен?
Название: Re: QTcpSocket QTcpServer скорости. Отправлено: Orfus от Июль 21, 2011, 14:51 _blockSize чему равен? 1480 байт, насколько вычитал 1500 это максимальный предел.Название: Re: QTcpSocket QTcpServer скорости. Отправлено: LisandreL от Июль 21, 2011, 15:06 1) Для сравнения попробуйте поставить значительно большее значение (раз в 10 хотя бы).
2) Попробуйте погонять файлы через, скажем Total Commander и посмотрите скорость там. Название: Re: QTcpSocket QTcpServer скорости. Отправлено: SimpleSunny от Июль 21, 2011, 16:27 Как посоветовали выше читать и писать блоками большего размера + желательно проверять, что отправили все что пытались отправить.
Запись Код
Чтение Код
Название: Re: QTcpSocket QTcpServer скорости. Отправлено: Orfus от Июль 21, 2011, 19:54 LisandreL,SimpleSunny спасибо за советы)
Как вы и говорили, дело по большей части было в размере блоков. Я наивно предполагал что сам составляю начинку пакета, а это было не так. Сегодня накидаю код виджета меняющего размер блоков без пересборки проекта, а завтра буду тестить. По резултату отпишусь. :) Кстати говоря вот такая штука в отправке файла Код дала прирост в 1МегаБайт. Думаю ещё поковырять её. Название: Re: QTcpSocket QTcpServer скорости. Отправлено: LisandreL от Июль 21, 2011, 21:52 Я наивно предполагал что сам составляю начинку пакета TCP — это поток данных. В отличии от UDP он не передаёт блоки целиком, а волен нарезать или склеивать(!) их так, как ему заблагорассудится (вернее как это реализовано в данной конкретной ОС).Название: Re: QTcpSocket QTcpServer скорости. Отправлено: Orfus от Июль 25, 2011, 10:16 При размере блока в 64мегабайта (благо оперативки нынче везде много ;D ) добился скорости в ~86Мбит, для файлов ~300Мбайт. Впринципе меня такая скорость уже устраивает, но всё же скажите имеет ли смысл писать следующий блок по пришествии сигнала
Код: void QIODevice::bytesWritten ( qint64 bytes ) [signal] Название: Re: QTcpSocket QTcpServer скорости. Отправлено: LisandreL от Июль 25, 2011, 10:44 Или это уже пустая трата времени в погоне за оставшимися 14 мегабитами О всех 14 даже не мечтайте. Не менее 5% идёт на служебную информацию в пакетах: http://sd.wareonearth.com/~phil/net/overhead/Название: Re: QTcpSocket QTcpServer скорости. Отправлено: Orfus от Июль 25, 2011, 11:08 О всех 14 даже не мечтайте. Не менее 5% идёт на служебную информацию в пакетах: http://sd.wareonearth.com/~phil/net/overhead/ Но получается часть из них ещё можно получить? Просто после того как в торрент клиенте видел 12МБайт\сек с 1го конкретного локального пира, считаю это число достижимым ::) P.S. Хотя это наверно уже лишнее. Передавать огромные файлы (>100мб) я не планировал, а для небольших человек физически разницы не увидит. Ещё раз спасибо за советы. Название: Re: QTcpSocket QTcpServer скорости. Отправлено: Gabriel.vs от Август 16, 2011, 15:13 Для увеличения скорости обмена данными в сети надо:
* Отключить "Nigle Algorithm" (m_sslSocket->setSocketOption(QAbstractSocket::LowDelayOption, 0)). Вот только не помню - возможно она по-умолчанию уже выключена. * Максимально уменьшить время, подставляемое в waitForReadyRead(), а ещё лучше эти методы на сигналы переписать. Как показали тесты, когда я переписывал VNC под реализацию в Qt, значение в waitForReadyRead крайне сильно влияло на задержки. Пришлось в единицу выставлять. Можно ещё вот в этом посте почитать (http://www.prog.org.ru/index.php?topic=17649.msg118258#msg118258 (http://www.prog.org.ru/index.php?topic=17649.msg118258#msg118258)), относительно скорости самих сокетов Qt'шных. * после каждого сенда даты flush() вызывать. Название: Re: QTcpSocket QTcpServer скорости. Отправлено: LisandreL от Август 16, 2011, 15:22 Просто после того как в торрент клиенте видел 12МБайт\сек с 1го конкретного локального пира Вообще-то многие клиенты как раз считают скорость со всем оверхедом, а не только полезных данных.Ну а так - в примерах Qt есть торрент клиент. Можете поэкспериментировать на предмет его максимальной скорости в локалке. Название: Re: QTcpSocket QTcpServer скорости. Отправлено: Orfus от Август 17, 2011, 16:22 Для увеличения скорости обмена данными в сети надо: После мучений с keepalive я сомневаюсь что setSocketOption вообще работает.* Отключить "Nigle Algorithm" (m_sslSocket->setSocketOption(QAbstractSocket::LowDelayOption, 0)). Вот только не помню - возможно она по-умолчанию уже выключена. * Максимально уменьшить время, подставляемое в waitForReadyRead(), а ещё лучше эти методы на сигналы переписать. Как показали тесты, когда я переписывал VNC под реализацию в Qt, значение в waitForReadyRead крайне сильно влияло на задержки. Пришлось в единицу выставлять. Можно ещё вот в этом посте почитать (http://www.prog.org.ru/index.php?topic=17649.msg118258#msg118258 (http://www.prog.org.ru/index.php?topic=17649.msg118258#msg118258)), относительно скорости самих сокетов Qt'шных. На сигналы то переписанное у меня как раз медленнее работало. Всё в одном слоте давало большую скорость.waitForReadyRead(1) попробую на досуге, по умолчанию там 30.000 По поводу кютешных сокетов. 86МБит меня вполне устраивает ;) Да, моя реализация кушала память весьма активно, но скушанные 100мб (а больше файлы с 90% вероятностью пересылатся не будут) меня не печалят, тем более что по окончанию отправки они освобождались. * после каждого сенда даты flush() вызывать. Это тоже стоит опробовать.Собственно говоря как гласит пословица "Если хочешь сделать хорошо - сделай это сам.". Было бы больше времени, я бы расписывал отправку/приём более детально, ну а пока что меня устраивает вариант с чтением по 64мегабайт при отправке. |