Обрыв соединения QTcpSocket |
Здравствуйте, гость ( Вход | Регистрация )
Обрыв соединения QTcpSocket |
BRE |
18.2.2010, 18:53
Сообщение
#21
|
Профессионал Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: 44 |
ну не знаю, я запускал в дебаге твой пример, так там клиент висел "без данных", пока сервер не переслал все полностью.. Ну да, ну да. Я там выше писал про цикл обработки событий... А у себя в примере добавить забыл. Добавь в цикл отправки сервера: QCoreApplication::processEvents() и все заработает. Или уж делать полноценную асинхронную отправку, тоже сложного ничего нет. |
|
|
OrSOn |
19.2.2010, 11:50
Сообщение
#22
|
Студент Группа: Участник Сообщений: 46 Регистрация: 8.12.2009 Пользователь №: 1289 Спасибо сказали: 0 раз(а) Репутация: 0 |
Да, что-то я тоже не заметил, спасибо, так работает)) Другое дело, что полный перенос сего кода в мой проект с целью проверки ни к чему не привел... Запускаю, а клиенту ничего не приходит (пока не напишу flush()). Причем если после вызова write() написать waitForBytesWritten(), то клиент получает сигнал readyRead(), но ему приходит только маленький кусок информации,а не все сразу. Может это быть связано с тем, что сервер передает через QThread со своим циклом событий? Увы, прислать файл не могу, ибо ограничения инета, закрыто добавление файлов. Но поток сделан так:
В конструкторе moveToThread( this ); А в функции run() одна функция exec() для создания собственного цикла. Далее работа потока идет чисто по сигналам... |
|
|
BRE |
19.2.2010, 11:59
Сообщение
#23
|
Профессионал Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: 44 |
Покажи подробно (закопипасть сюда) класс этого потока, скорее всего дело в нем.
Помимо переноса самого объекта потока в контекст этого потока, нужно переносить и все объекты, которые будут работать внутри него. |
|
|
OrSOn |
19.2.2010, 12:15
Сообщение
#24
|
Студент Группа: Участник Сообщений: 46 Регистрация: 8.12.2009 Пользователь №: 1289 Спасибо сказали: 0 раз(а) Репутация: 0 |
Ну все будет сложно сюда перенести, ибо много, я ключевые вещи вставлю...
Раскрывающийся текст Объявление класса
конструктор
Run
Функция установки текущего рабочего сокета на поток (сокет создается в основном потоке и передается на обратоку в один из потоков)
Соответственно, вызывается эта функция из основного потока, после чего поток начинает реагировать на появление информации в сокете. Отвязывается сокет от потока при завершении передачи или при обрыве связи
Вот примерно такая структура... |
|
|
SABROG |
19.2.2010, 12:25
Сообщение
#25
|
Профессионал Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: 34 |
Если ты коннектишь сигнал объекта к слоту этого же объекта, то второй указатель (this) можно опустить. Первый this опускать нельзя, т.к. метод статический, статические методы ничего не знают об объектах.
Почему выбран именно Qt::DirectConnection? Сокет принадлежит тому же потоку, что и объект QThread? |
|
|
OrSOn |
19.2.2010, 12:31
Сообщение
#26
|
Студент Группа: Участник Сообщений: 46 Регистрация: 8.12.2009 Пользователь №: 1289 Спасибо сказали: 0 раз(а) Репутация: 0 |
Сокет принадлежит главному потоку, объект NThread тоже создается в главном потоке, но без родителя. DirectConnection() выбрано, потому что так если соединение рвется, то я НЕМЕДЛЕННО переношусь в обработку разрыва, а если оставить в очереди, то буду пытаться работать с разорванным сокетом, что приведет к ошибке и потере времени...
Сообщение отредактировал OrSOn - 19.2.2010, 12:32 |
|
|
SABROG |
19.2.2010, 13:01
Сообщение
#27
|
Профессионал Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: 34 |
Это не правильно. Соединение не должно быть прямым между двумя потоками.
Цитата а если оставить в очереди, то буду пытаться работать с разорванным сокетом, что приведет к ошибке и потере времени...
Не спасет? Потеря времени будет только если размер твоего блока 1 байт. Если есть сомнения насчет валидности указателя socket, то его можно обернуть в QWeakPointer:
Сообщение отредактировал SABROG - 19.2.2010, 13:07 |
|
|
OrSOn |
19.2.2010, 13:02
Сообщение
#28
|
Студент Группа: Участник Сообщений: 46 Регистрация: 8.12.2009 Пользователь №: 1289 Спасибо сказали: 0 раз(а) Репутация: 0 |
У меня и так эта проверка стоит, согласен, можно убрать... Но проблему это не решает((( Все равно ничего не меняется..
|
|
|
BRE |
19.2.2010, 13:12
Сообщение
#29
|
Профессионал Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: 44 |
Сокет принадлежит главному потоку, а должен принадлежать потоку, который его обслуживает.
А вообще там столько всего наверчено. Для чего? Нужно выполнить какое-то действие - создал поток, настроил его и запустил... Он отработал, забрал у него результат, убил. Уверен, что если распишешь задачу, можно будет все упростить в несколько раз... |
|
|
SABROG |
19.2.2010, 13:19
Сообщение
#30
|
Профессионал Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: 34 |
Смотри что получается. Сокет находится в гуишном потоке, его обслуживает отдельный поток, это означает, что когда ты вызываешь метод write() ты напрямую обращаешься к методу объекта. В результате ты пытаешься записать данные из одного потока в другой напрямую.
Если ты не хочешь переносить сокет в тот же поток, который его обслуживает, то убедись, что обслуживающий поток эмитит сигнал о начале записи каких-либо данных и продолжает своё выполнение в то время, когда основной поток что-то пишет в сокет. Если ты все-таки хочешь вызывать read/write в обслуживающем потоке, то сокет должен принадлежать ему. Просто запомни, что любое взаимодействие между двумя объектами находящимися в разных потоках должно происходить через сигналы или события. Не должно быть никаких прямых вызовов методов одного объекта у другого. Конечно ничего не случиться, если метод threadsafe, но таковыми являются не все. |
|
|
Текстовая версия | Сейчас: 4.12.2024, 12:52 |