Название: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: vulko от Март 03, 2014, 08:17 Всем привет.
Сделал tcp сервер и клиент для непрерывного обмена данными. Сервер - слегка переделанный fortune server, клиент писался с нуля, т.к. работает в отдельном потоке. Суть работы такая - клиент делает запрос серверу, тот отвечает записывая в сокет 128 байт данных. Клиент получает, десериализует данные и дисконнектится. По сигналу дисконнекта, небольшой delay и снова запрос данных с сервера. И так до бесконечности. В принципе все прекрасно работает, но иногда приходит сокет размера 4224 байт. Откуда берется такой сокет не понимаю... Пока что просто игнорирую все сокеты размером не 128 байт, но все таки хотелось бы понять что это за пакет такой... Заранее спасибо за ответы. Название: Re: Большие пакеты с непонятно чем при передаче через QTCPSocket Отправлено: OKTA от Март 03, 2014, 09:26 Для начала прочитайте, что такой "сокет" и что такое "пакет tcp", чтобы не путаться в определениях. И да, как уже писал в другом треде, посмотрите, что в этих данных лежит + следите за тем, что и сколько байт отправляет сервер.
Название: Re: Большие пакеты с непонятно чем при передаче через QTCPSocket Отправлено: vulko от Март 03, 2014, 10:17 Для начала прочитайте, что такой "сокет" и что такое "пакет tcp", чтобы не путаться в определениях. И да, как уже писал в другом треде, посмотрите, что в этих данных лежит + следите за тем, что и сколько байт отправляет сервер. Про отличия в курсе, не хотелось тавтологию устраивать. Если так смущает, пусть будет сокет, про пакеты забудем ;) Добавил небольшой кусок кода для логирования необычного пакета: Код: if (pTcpSocket->size() != 128) { Судя по логам, в буфере сокета лежит фигпойми что... Цитировать QVariant(bool, true) ______________________________________ ______________________________________ Если я правильно понимаю, QVariant это в принципе что угодно... Возможно неверная логика сервера? Не хватает чего-то после write()? Кстати сервер рапортует всегда о том что отправил 128 байт, огромные сокеты только у клиента... Код: QTcpSocket tcpSocket; п.с. вышеприведенный код сервера выполняется в отдельном потоке (как в fortune server). Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: Fregloin от Март 03, 2014, 10:39 очевидно что данные пакетов буферизируются, и не вычитываются полностью клиентом.
если есть уверенность что пакеты всегда длиной 128 байт, можно задать размер буфера чтения сокета этому объему (это большой костыль, но сможет помочь поидее). приведите код чтения сокета, что бы было понятней как вы читаете данные. Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: OKTA от Март 03, 2014, 10:44 Тавтология не имеет здесь места вообще) Сокет и пакет абсолютно разные вещи и лучше использовать понятия в нужном месте и в нужное время, а то может встать боком в будущем - на каком-нибудь собеседовании ляпнете и будет ахтунг :-[
А еще лучше для теста увеличьте размер пакета и посмотрите, увеличивается ли размер "залипшего" пакета. Слипание пакетов в один - частая проблема с сокетами по началу. Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: vulko от Март 03, 2014, 11:05 очевидно что данные пакетов буферизируются, и не вычитываются полностью клиентом. если есть уверенность что пакеты всегда длиной 128 байт, можно задать размер буфера чтения сокета этому объему (это большой костыль, но сможет помочь поидее). приведите код чтения сокета, что бы было понятней как вы читаете данные. не совсем понимаю как могут пакеты слипнуться, если делается дисконект сокета, прежде чем запросить новую порцию данных... костыль конечно можно запилить, но можно и оставить текущий костыль с игнором сокета с буфером ненужного размера... в любом случае это временная имплементация, и возможно вообще придется отказаться от высокоуровневых апи и перейти на сишный код... так что смысла особого в таком костыле не вижу. интересует именно причина. возможно неверно использую Qt'шное апи для работы с сокетами... запись: Код: void ServerThread::run() чтение Код: void IncomingDataHandler::readData() Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: OKTA от Март 03, 2014, 11:14 Фишка в том, что когда используется tcpSocket.write(block);, данные пишутся не прямо в сеть грубо говоря, а в буффер. И дальнейшее - уже дело протокола - или он сразу отправит данные или потом. Можно после write поставить flush попробовать.
Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: vulko от Март 03, 2014, 11:42 Фишка в том, что когда используется tcpSocket.write(block);, данные пишутся не прямо в сеть грубо говоря, а в буффер. И дальнейшее - уже дело протокола - или он сразу отправит данные или потом. Можно после write поставить flush попробовать. flush не помогает, пробовал. поскольку 128 байт отправляю, решил его вообще убрать... это понятно что сетевые пакеты это не тоже самое что буфер сокета... и я бы мог понять откуда вдруг берется такой пакет, если бы например я бы записывал туда непрерывно... но я пишу порцию 128 байт, дисконекчу сокет на сервере, на клиенте буфер приходит, читается, уходит в другой поток на обработку и приходит сигнал disconnected(), после которого уже идет новый запрос на сервер, и тот снова отправляет 128 байт... как может придти буфер в 4224 байта непонятно... то ли это кривость сокетов в qt, то ли виртуалка виновата... хз даже... на винде что ли попробовать это безобразие протестить... Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: OKTA от Март 03, 2014, 11:47 Попробуй ради интереса прочитать первые 128 байт пакета этого кривого, словно там нормальный твой пакет лежит)
Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: Bepec от Март 03, 2014, 12:01 А по хорошему надо бы снифером полирнуть пакеты и выложить парочку нормальных и свой ненормальный :D
Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: vulko от Март 03, 2014, 12:29 Попробуй ради интереса прочитать первые 128 байт пакета этого кривого, словно там нормальный твой пакет лежит) sigsegv. собсно с этого и началось, только потом выяснилось что пакет приходит не 128 байт... А по хорошему надо бы снифером полирнуть пакеты и выложить парочку нормальных и свой ненормальный :D с удовольствием. я тока wireshark'ом пользовался. что под линух посоветуешь? чтобы не через package manager тока, а с инсталятором был... а то у меня линух супер кастомный какой-то... :/ п.с. попробовал под виндой (qt 5.2.0 + mingw 4.8), так тут вообще вылетает при иногда при десериализации последнего поля структуры. попробовал добавить перед for'ом waitforreadyread (хотя судя по описанию это надо не в хэндлере сигнала readyread вызывать...:) ), теперь на нём sigsegv... причем это тока на дебаге происходит, в релизе все чудесно...)) я конечно и раньше догадывался, что лучше жабы ничего кроссплатформеного нет... теперь точно уверен))) Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: OKTA от Март 03, 2014, 12:39 http://www.ethereal.com
Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: vulko от Март 03, 2014, 13:02 http://www.ethereal.com там какой-то cloud service... сайт не валидный уже Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: OKTA от Март 03, 2014, 13:12 Тогда http://www.wireshark.org/ ;D ибо это одно и тоже ;D
Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: vulko от Март 03, 2014, 13:49 Тогда http://www.wireshark.org/ ;D ибо это одно и тоже ;D попробовал под виндой wireshark'ом посмотреть, но ничего толкового из этого не вышло... порт для сокета выставляю 777, по факту пакеты идут левыми портами... в общем ничего толкового из этих пакетов я не понял... все таки это не какой-нибудь sip, где все предельно четко и понятно... если вы понимаете в этом что-то, могу закинуть сюда pcap. однако логирование под виндой и дебаг кое-что помогли выявить... (под виртуалкой линуха в qt creator'е не вижу почти никакие локальные переменные и не могу оценивать выражения и т.п... не отображаются тупо...). в общем модифицировал немного код: Код: int size = pTcpSocket->size(); и что же я увидел... Цитировать socket data recieved: 4224 bytes wrong socket 4224 : 128 128 ________________________________________________________ 128 ________________________________________________________ то есть на момент попадания в if (size != 128), размер буфера сокета из 4224 вновь превратился в 128, и в QDataStream (in) лежит массив из 128 байт... чудесно... возникла идея, возможно виновата QEventLoop? Т.к. сокет обрабатывается в отдельно потоке и после tcpSocket->connectToHost() делается loop.exec, которая закончится только когда придет сигнал disconnected() от сокета... Может в этом дело? Код: void IncomingDataHandler::run() Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: OKTA от Март 03, 2014, 14:18 Я конечно не специалист, но это нормально делать exec лупу в while?
Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: Bepec от Март 03, 2014, 14:32 Ххы.
Интересно как ТС собирается останавливать этот поток, если нигде нет прерывания лупа :) Не, по архитектуре он там необходим как бы, но вот что дальше :) Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: vulko от Март 03, 2014, 15:41 Ххы. Интересно как ТС собирается останавливать этот поток, если нигде нет прерывания лупа :) Не, по архитектуре он там необходим как бы, но вот что дальше :) running = false, socket disconnect - у лупа вызывается слот quit(). а вообще поток не должен прерываться, пока работает приложение ;) п.с. все это конечно интересно, но все таки хотелось бы понять причину проблемы, описанной в этом топике ;) Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: Bepec от Март 03, 2014, 15:44 А по хорошему надо бы снифером полирнуть пакеты и выложить парочку нормальных и свой ненормальный :D Уже ответил я вам. Работа Qt сомнению не подлежит (хотя бывает, бывает. Испортить можно всё). Подлежит сомнению ваш код и ваши данные и ваша сеть и ещё всё то, что у вас :D PS вы уже херн*й страдаете полдня. Разберитесь с сниффером и в путь. А без фактов могу ток посоветовать обратиться к духу ванги :P Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: vulko от Март 03, 2014, 16:29 А по хорошему надо бы снифером полирнуть пакеты и выложить парочку нормальных и свой ненормальный :D Уже ответил я вам. Работа Qt сомнению не подлежит (хотя бывает, бывает. Испортить можно всё). Подлежит сомнению ваш код и ваши данные и ваша сеть и ещё всё то, что у вас :D PS вы уже херн*й страдаете полдня. Разберитесь с сниффером и в путь. А без фактов могу ток посоветовать обратиться к духу ванги :P Данные у меня генерируются при старте сервера, с каждым запросом к ним рандомно +/- небольшая дельта. Сеть... ну ладно линух под виртуалкой, но и на винде та же история. Qt сомнению не подлежит... ой не смеши :) Любой мало мальски большой продукт подлежит сомнению. Ванговать смысла не вижу. tcpSocket->size() периодически возвращает 4224 байта, а через пару строк кода уже 128 байт. Причина тут может быть как в сети, так и в QT, так и в конкретной реализации, т.к. есть поток, есть луп, который обрабатывает ивенты и месаджи. Прикрепил pcap файл, кривой размер пакета случился почти сразу. Собсно после этого сокет не использовался. Если вы можете что-то понять из этого, буду благодарен. Я кроме как размера физических пакетов, ничего полезного не увидел. В основном пакеты там около 60 байт, есть некоторые по 1514 байт, но определить где мои пакеты, а где не мои я не могу. Как уже ранее упоминал, порты там совершенно левые, а не 777 порт, который я использую при коннекте к серверу. Название: Re: "Левые" пакеты с непонятно чем при передаче через QTCPSocket Отправлено: Bepec от Март 03, 2014, 16:46 offtop: чем чаще проект используется, тем меньше ошибок. А по частоте использование ваш код проигрывает Qt :P
А теперь настало время пыток :) Ip вашего сервера и клиента. (Что откуда и куда) Адрес порта подключенного клиента (спокойно выясняется на клиенте peerPort () или localPort () ). пакет ваших данных. Точнее блок, отправляемый сервером выведите в QByteArray().toHex(). И тогда уже можно что-то смотреть :D PS и вообще хорошо, если вы этот блок сделаете постоянным(одинаковым), чтоб сервер шмалял одно и то же :) update: у вас там принтер не шалит? :D HP фирмы :P Это ваш загадочный пакет. Код: ToneValue.1.HPPrintOnBothSidesManually.False.HPPaperSizeDuplexConstraints.EXECUTIVE.HPMediaTypeDuplexConstraints. update: а мб это и есть ваш ответ :D Драйвер скорее всего данные эти забирает сразу. Потому в буфере у вас остаётся только ваш пакет. |