Поиск:

Ответ в темуСоздание новой темы Создание опроса
> QTcpSocket, правильное использование 
V
    Опции темы
Sality123
Дата 24.11.2011, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



Всем привет, у меня работает связка сервер клиент,  и при отправке обьема больше 4к в одном пакете, случаются случаи када пакет доходит не полностю, замечена была потеря 100 байт.

сервер:


 
Код

Senddata( toSend )
{
    if (state() == ConnectedState)
    {
        QByteArray toSend = serialize(vVar);
        qDebug()<< "lenth"<<   toSend.length();
       qDebug()<< " sent:"<<   write(toSend);
        m_vmSendBuffer.clear();
        return waitForBytesWritten();
    }
  }


прием на клиенте

Код

if (state() == ConnectedState)
    {
        int ba = bytesAvailable();

        QByteArray read = readAll();
        qDebug()<<"ba: "<< ba << "lenth: " << read.length();
 
    }


вот результат дебага
сервер:
lenth:  1632 sent:  1632 
lenth:  453 sent:  453 
lenth:  165 sent:  165 
lenth:  4480 sent:  4480 
lenth:  4428 sent:  4428 
lenth:  4428 sent:  4428 

клиент:
ba:  1632 lenth:  1632 
ba:  453 lenth:  453 
ba:  165 lenth:  165 
ba:  4380 lenth:  4380 
ba:  4428 lenth:  4428 
ba:  4428 lenth:  4428

переменая ba - указывает, сколько доступно в сокете для чтения. Как видно на 4 строчке сервер отправил lenth:  4480 sent:  4480  а клиент получил ba:  4380 lenth:  4380 ....
куда делись сто байт неясно. Если величина пакета до 4к, то такого не случается.

Сервер и клиент работают на локалхосте.

Укажите на мою ошибку пжл.


ПС : случается фрагментирование пакета случайно... он может быть и пятым и первым... может повторится фрагментирование


Это сообщение отредактировал(а) Sality123 - 24.11.2011, 13:52
PM MAIL   Вверх
bsa
Дата 24.11.2011, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



В цикле читать пробовал?
PM   Вверх
Sality123
Дата 24.11.2011, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



а смысл? када приходит сигнал readyRead() , значит данные готовы для чтения, я перепроверяю их размер через bytesAvailable(). и делаю readall() что означает считать все данные с буфера... и данные авилайбл и считаные данные одинаковы... тоесть я все считываю у буфера
PM MAIL   Вверх
bsa
Дата 24.11.2011, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



Sality123, вообще-то, данные приходят не все сразу, а постепенно - пакетами. Пришел первый пакет и ты его прочитал. А вот второй пакет, в котором остатки данных, ты проигнорировал.
PM   Вверх
Sality123
Дата 24.11.2011, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



как тада быть? я всегда думал что пакет приходит весь, который я отправил...

Что тада сделать? 
PM MAIL   Вверх
bsa
Дата 24.11.2011, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



Цитата(Sality123 @  24.11.2011,  15:19 Найти цитируемый пост)
Что тада сделать?  

цикл.

Обычно, протокол прикладного уровня каким-то образом определяет, сколько данных необходимо принять. Если передача идет текста, то конец пакета может обозначаться символом перевода строки, например...
PM   Вверх
Sality123
Дата 24.11.2011, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



можно кусок кода что имено пихануть в цикл, и сколько его крутить... что-то я совсем не понимаю как это реализовать.
PM MAIL   Вверх
bsa
Дата 24.11.2011, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



Sality123, крутить пока не придут все данные или не истечет время их ожидания.
Код
while((data.size() < requiredSize) && socket->waitForReadyRead(1000))
   data += socket->readAll();
if (data.size() < requiredSize)
   //ошибка - истекло время ожидания данных


Это сообщение отредактировал(а) bsa - 24.11.2011, 15:14
PM   Вверх
Sality123
Дата 24.11.2011, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



data.size() < requiredSize

а с чем я сравниваю data.size() ? 
что это за переменная requiredSize
PM MAIL   Вверх
bsa
Дата 24.11.2011, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



Sality123, эта переменная, которая содержит размер посылаемых данных. Если этот размер определить никак нельзя, то отправляй его сначала с сервера.
PM   Вверх
Sality123
Дата 24.11.2011, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



зависает просто в цикле, так как пакет не приходит того размера, который я отправляю... если отправить 20кбайт то бывает что приходит 5 - 8. Я вычитал что сокет сам разбивает пакеты на куски, тада неясно как получить остальные куски...

PM MAIL   Вверх
Sality123
Дата 24.11.2011, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



Проблема решена. 
Вобщем, как оказывается, сокет разбивает произвольно пакеты на кусочки, которые нужно собирать вручную. Если допустим отправляется байтэрай 20кб. То придет он 5 раз по 4кб. Которые нада собрать в кучу.


Полезно для новичков, так как об этом важнейшем нюансе ни слова нету нигде.
PM MAIL   Вверх
Sality123
Дата 24.11.2011, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 10.3.2011

Репутация: нет
Всего: нет



Проблема решена. 
Вобщем, как оказывается, сокет разбивает произвольно пакеты на кусочки, которые нужно собирать вручную. Если допустим отправляется байтэрай 20кб. То придет он 5 раз по 4кб. Которые нада собрать в кучу.


Полезно для новичков, так как об этом важнейшем нюансе ни слова нету нигде.
PM MAIL   Вверх
Artemon
Дата 25.11.2011, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а ты мне нравишься
***


Профиль
Группа: Завсегдатай
Сообщений: 1771
Регистрация: 24.2.2004
Где: Челябинск

Репутация: 2
Всего: 20



bsa, в данном случае цикл не поможет, т.к. насколько я понял, используется асинхронная модель.
Но кусочками всеравно придется принимать smile


--------------------
Контроль топлива на топливозаправщиках, мониторинг автотранспорта, расчет зарплаты водителей www.rscat.ru
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0507 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.