Здравствуйте!
Есть программа сервер на одном компьюетер и программа-клиент на другом,
обе на Qt, общаются по сети. Кроме постоянно идущих данных, клиент иногда
получает от сервера команды в виде массива из 8 байтов, QTcpServer передаёт,
а QtcpSocket принимает, другие, чем для предачи данных. Клиент в Ubuntu-11.04,
сервер в Ubuntu 10.04, Qt-4.7.x.
Несмотря на маленький размер команды, клиент иногда получает ложные команды,
которых сервер не посылал. Конкретно, запускается клиент, сервер тут же
посылает ему команду, затем по щелчку мыши другую, она принимается и
исполняется правильно, но затем клиент принимает ещё 8 байтов, непонятно отчего.
Я пробовал в клиенте вызывать waitForReadyRead(timeout) перед read(), либо использовать
readAll() и проверять, что пришли все 8 байтов. Это помогает при передаче и приёме
больших посылок - jpg-файлов, но в случае с командой не помогло, всё равно
получаются лишние 8 байтов. В чём причина и как бороться, м.б., кто-нибудь знает?
Пётр.
QTcpSocket->read()
программа сервер на одном компьюетер и программа-клиент на другом
А что за программа и как проверить что происходит её не имея? Примерно так:

Там нечего проверять - с одной стороны write(), с другой read(),
а что происходит, я рассказал. После приёма посланной команды якобы принимаются
ещё раз 8 байтов.
Пётр.
Что то в памяти в этом плане все зашорено.... Сейчас нет времени воскрешать.
Если не ошибает память могут быть проблемы связанные с выравниванием.
Там есть разница в условиях при передаче первых двух команд, принимающихся правильно и 3-ей,
принимающейся неправильно. После 2-й команды по тому же кабелю клиент начинает получать
jpg-файлы с частотой 10 раз в секунду, через другой сокет, а до этого линия свободна. Однако 3-я
команда стабильно приходит с одними и теми же ошибками, 2-й и 6-й байты.
Пётр.
Там нечего проверять - с одной стороны write(), с другой read(),
а что происходит, я рассказал. После приёма посланной команды якобы принимаются
ещё раз 8 байтов.
Пётр.
В любую передачу данных по протоколу TCP необходимо первым делом засовывать размер передаваемого блока.
К примеру:
QByteArray out;
out << quint16(0);
out << "суем данные"
out << "в первые два байта засовываем out.size();"
На стороне клиента, читаем первые два байта(определяем как размер сообщения) и ждем прима.
[quote=Peter]Там нечего проверять - с одной стороны write(), с другой read(),
а что происходит, я рассказал. После приёма посланной команды якобы принимаются
ещё раз 8 байтов.
Пётр.
В любую передачу данных по протоколу TCP необходимо первым делом засовывать размер передаваемого блока.
К примеру:
QByteArray out;
out << quint16(0);
out << "суем данные"
out << "в первые два байта засовываем out.size();"
На стороне клиента, читаем первые два байта(определяем как размер сообщения) и ждем прима.[/quote]
Несколько месяцев назад я так делал, но тогда размер передаваемого массива был заранее неизвестен.
Если вы имеете в виду именно протокол TCP, то я же сам не подготавливаю его заголовок, это делает Qt.
Такой небольшой масссив - 8 байтов - должен передаваться за один раз. Конкретно, в 3-й раз посылается
1 3 2 0 1 0 -1 -1а принимается всегда
1 1 2 0 1 -1 -1 -1тогда как предидущая посылка, после приёма которой клиент начинает получать jpg от сервера через
другой сокет, принимается правильно:
1 3 2 0 1 -1 -1 -1Пётр.
Не глядя в исходники трудно гадать. Такое ощущение, что у вас вообще проблема не там где ищите.
Попробуйте передать во второй заход:
1 2 3 4 5 6 7 8
А в третий
11 12 13 14 15 16 17 18
И посмотреть что приходит
Если бы я знал, в чём проблема, то, наверное, нашёл бы способ её обойти.
Похоже, что неправильный приём команды начинается после того, как клиент
по 2-й команде начинает принимать jpg от того же сервера по тому же
интерфейсу. Но, возможно, попробую передать 3-ю команду произвольную.
Пётр.
Похоже, что неправильный приём команды начинается после того, как клиент
по 2-й команде начинает принимать jpg от того же сервера по тому же
интерфейсу.
Не понял.
У вас установлено одно соединение между клиентом и сервером?
Третья команда отправляется сервером и одновременно передается jpg?
Как у вас организовано какие байты и к чему относятся?
Или у вас третья команда идет уже после приема jpg?
Если бы я знал, в чём проблема, то, наверное, нашёл бы способ её обойти.
А я и не предлагаю обойти. Я пытаюсь прикинуть где у вас может быть ошибка.
Вы не можете выкусить минимальный кусок кода, что б ни чего лишнего, но происходило именно так как происходит?
[quote="Peter"]Похоже, что неправильный приём команды начинается после того, как клиент
по 2-й команде начинает принимать jpg от того же сервера по тому же
интерфейсу.
Не понял.
У вас установлено одно соединение между клиентом и сервером?
Третья команда отправляется сервером и одновременно передается jpg?
Как у вас организовано какие байты и к чему относятся?
Или у вас третья команда идет уже после приема jpg?[/quote]
Да, 3-я команда посылается клиенту после того, как он по 2-й начал приём jpg и я это говорил.
По 2-й команде он связывается с сервером через другой сокет и другой порт и
начинает через него получать jpg, т.е два соединения, но один интерфейс eth.
Т.е. для получения команд используется одна тройка сервер-сокет-порт, а для получения
jpg - другая и jpg идут 10 раз в секунду.
При этом передача jpg и команд никак не синхронизированы. М.б., использовать mutex,
чтобы не было наложения? Но ведь протокол TCP и так обязан обеспечивать доставку пакетов.
Пётр.
При этом передача jpg и команд никак не синхронизированы. М.б., использовать mutex,
чтобы не было наложения? Но ведь протокол TCP и так обязан обеспечивать доставку пакетов.
не. Дело точно не в TCP.
Это работает в разных потоках?
[quote="Peter"]При этом передача jpg и команд никак не синхронизированы. М.б., использовать mutex,
чтобы не было наложения? Но ведь протокол TCP и так обязан обеспечивать доставку пакетов.
не. Дело точно не в TCP.
Это работает в разных потоках?[/quote]
Да, для получения jpg создаётся отдельный поток и их может быть до четырёх.
Это работает, но раньше такие потоки создавались не по одному, а сразу, сколько надо,
по команде, котрую я здесь назвал 2-й. jpg от них принимает одна функция на всех,
но сейчас запускается только один поток.
Пётр.
Можете "отключить" передачу jpg. Пусть просто идет та череда команд, что должна идти.
Начинайте отключать по максимуму функционал не относяящийя непосредственно к передаче и приму команд
Можете "отключить" передачу jpg. Пусть просто идет та череда команд, что должна идти.
Тогда нечего будет проверять. Ведь первые две команды, пока не запущен прием jpg,
принимаются правильно, а неправильно принимается 3-я. Можно будет проверить разве,
как пройдёт 3-я команда, если она будет не на запуск нового потока, как сейчас,
а на закрытие уже запущенного.
Программа ничего не делает кроме того, что принимает jpg, декодирует их и выводит на экран.
Для неё является нормальным, когда при этом приходят команды. Команды, кроме 1-й,
посылаются по щелчку мыши.
Пётр.
Попробовал дать 3-ю команду на остановку потока:
1 3 2 0 -1 -1 -1 -1пришло то же самое, что и при команде запуска нового:
1 1 2 0 1 -1 -1 -1откуда оно берётся, непонятно.
Пётр.
Можете рассказать подробнее об этих 8 байтах.
- Какова их структура (хотя бы каждый байт самостоятельная величина, или некоторые величины имеют размер больше байта).
- как вы работаете с этими байтами (просто массив, струтура ....)
- как анализируете значения (например операции логические сравнения или просто условные)....
\Можете рассказать подробнее об этих 8 байтах.
- Какова их структура (хотя бы каждый байт самостоятельная величина, или некоторые величины имеют размер больше байта).
- как вы работаете с этими байтами (просто массив, струтура ....)
- как анализируете значения (например операции логические сравнения или просто условные)....
Не понял, что от меня требуется. Все величины по размеру укладываются в байт, сам массив для их приёма - char.
Отладочная печать есть на обеих сторонах, из сервера посылаемый массив печатается правильно, в клиенте
сразу после приёма 3-й команда печатается неправильно. Наверное, что-то я делаю неправильно, но не пойму что.
По этому соединению передаются только команды.
Рётр.