Russian Qt Forum

Qt => Работа с сетью => Тема начата: Денис от Декабрь 27, 2014, 15:59



Название: [РЕШЕНО] QTcpSocket как отследить потерю пакета ?
Отправлено: Денис от Декабрь 27, 2014, 15:59
Реализую модель связи Модем->Сервер от модема сообщения приходят всегда а от сервера бывают не доходят так как уровень сигнала может меняться у Модема и по каким то другим причинам ... Так вот собственно момента: как со стороны сервера отследить дошел пакет до клиента или нет посредством QTcpSocket ?


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: Bepec от Декабрь 27, 2014, 17:07
Эммм... система запрос ответ спокойно решит ваш вопрос.


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: ksk- от Декабрь 27, 2014, 17:09
Через QTcpSocket нельзя отслеживать пакеты. Это более высокий уровень.


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: Денис от Декабрь 27, 2014, 18:27
Так TCP ж должен предоставлять методы гарантированной доставки в отличии от UDP сокет ? Или я не прав ?
Собственные методы это понятно а встроенные в сокет ?


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: Денис от Декабрь 27, 2014, 22:04
Есть еще одна проблема при передачи данных внутри обработчика void QHttpServer::serverReadClient(), когда данные пришли, они доходят до клиента, но при попытке передачи данных вне обработчика данные доходят только при закрытии потока ?  ???
Никак не могу понять почему, помогите плз ?


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: ksk- от Декабрь 27, 2014, 22:33
Так TCP ж должен предоставлять методы гарантированной доставки в отличии от UDP сокет ? Или я не прав ?

Да, TCP предполагает гарантированную доставку данных. Сам протокол, как правило, реализован на уровне ОС. QTcpSocket - лишь удобный интерфейс. Но ты говоришь, что у тебя сообщения не доходят. Возможно, ты что-то делаешь на так, как надо. Не совсем ясна суть твоей проблемы. Растолкуй более подробно, желательно, с кусками кода.

И, кстати, что ты подразумеваешь под пакетами? Я подумал на IP-пакеты.


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: Денис от Декабрь 27, 2014, 22:42
Так TCP ж должен предоставлять методы гарантированной доставки в отличии от UDP сокет ? Или я не прав ?

Да, TCP предполагает гарантированную доставку данных. Сам протокол, как правило, реализован на уровне ОС. QTcpSocket - лишь удобный интерфейс. Но ты говоришь, что у тебя сообщения не доходят. Возможно, ты что-то делаешь на так, как надо. Не совсем ясна суть твоей проблемы. Растолкуй более подробно, желательно, с кусками кода.

И, кстати, что ты подразумеваешь под пакетами? Я подумал на IP-пакеты.

Но это не всегда происходит, часто пакеты доходят но бывают моменты когда и не доходят:
Код:
            // Sending answer
            do {
                clientSocket->write((char *)&answer,1);
            } while(!clientSocket->waitForBytesWritten(100));
            clientSocket->flush();

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


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: Денис от Декабрь 28, 2014, 18:49
Кое-что выяснилось: отправить можно и вне обработчика чтения, непонятно лишь почему иногда происходит буферизация пакетов, а при закрытии они все разом отправляются на сервер, как бы отключить буферизацию в QTPSocket ... У меня с сервера поступают одиночные байты подтверждения, бывают соединения когда пакеты поступают сразу же и общение продолжается, но бывает когда сервер почему-то буферизирует эти одиночные байты и они отправляются только при закрытии сокета ? Правда я почитал, что отключить буферизацию пакетов в QTCPSocket нельзя, но как тогда быть если мне необходимо отправить одиночные пакеты малого размера UDP поднимать ?


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: nwnclv от Декабрь 29, 2014, 00:24
Код
C++ (Qt)
clientSocket->write((char *)&answer,1);

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

Цитировать
сервер почему-то буферизирует эти одиночные байты
Тут 2 варианта: либо так устроен класс (буферизует сам) и ты чего-то недочитал, либо это отрабатывает алгоритм Нейгла (https://en.wikipedia.org/wiki/Nagle%27s_algorithm), который отключается путем установки флага TCP_NOWAIT.


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: Bepec от Декабрь 29, 2014, 00:49
Ошибка в его коде и/или системе. Но т.к. системы пишутся и проверяются, а его код нет, ставлю 99% на его код :D


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: qate от Январь 05, 2015, 08:29
Система никак не скажет приложению о доставке пакета или его потери - очень подробно это описано в книге "Снейдер. Эффективное программирование TCP/IP. Библиотека программиста. Питер, 2002"
Необходимо делать свои подтверждения.


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: PimenS от Январь 05, 2015, 09:35
Вообще странно, что QTcpSocket теряет пакеты.
У меня уже 3 года работает обмен между 10-ю базами данных на QTcpSocket.
Каждые 5 минут между ними происходит передача данных от 1 байта до 300 килобайт. Ни разу не видел чтобы пакет потерялся.

Может все-таки неправильно прием данных организован?


Название: Re: QTcpSocket как отследить потерю пакета ?
Отправлено: Денис от Январь 20, 2015, 21:56
Тема закрыта: проблема была в самом свистке (модеме).