Russian Qt Forum
Ноябрь 23, 2024, 01:27 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Проблема с записью в сокет.  (Прочитано 4047 раз)
naico
Гость
« : Ноябрь 14, 2008, 11:22 »

Привет. Столкнулся со следующей проблемой:

В GUI-треде срабатывает action, по которому нужно послать с помощью сокета сообщение удаленной машине, сообщение посылается (т.е write возвращает правильный размер), но не читается на обратном конце.
Стал разбираться, выяснилось следующее, если после срабатывания action'a управление передается на слот и в нем же происходит отправка данных на сервер, то все хорошо, все работает. Если же управление приходит на слот, но отправка непосредственно происходит в других ф-ях (слотах также), то сокет остается пустым.

Детальнее,
Запись в сокет:
Код:
void postman :: sendMessageToServer (QByteArray & darr)
{
QTcpSocket *sock ;
try
{
sock = new QTcpSocket;
if (!sock) throw tr("Ошибка выделения памяти");

sock->connectToHost(_ip, _port);
if (!sock->waitForConnected(1000)) throw tr ("Сервер не доступен");
int i = sock->write (darr);
if ( i == -1 ) throw QObject :: tr("Проблема связи с сервером") ;
sock-> deleteLater();
}
catch (QString s) {delete sock; emit errorHappens(s);}
}

 если приходит сигнал соответствующий и управление передается на

Код:
void Arm :: sendRulesToOne (QString data)
{
/*Идет создание правильного сообщения по вводимым данным, не думаю, что это важно, управление остается в этой ф-ии*/
bool f = sendMessageToServer (a);
        /*Идет проверка на значение f*/
}

то все хорошо.

Теперь, другая ситуация, когда управление переходит на

Код:
void Arm :: sendRulesToGroup (QString data, QList<QString> aList)
{
QString _lastAgent = currentEditAgent;
for (int i = 0 ; i < aList.size(); i++)
{
currentEditAgent = aList[i];
sendRulesToOne(data);
}
currentEditAgent = _lastAgent;
}
возникает описанная проблема.

Далее, создал контекстное меню, при срабатывании action'ов опять посылаются сообщения удаленной машине.
Заметил, что работают исключительно функции-слоты, в которых непосредственно осуществляется запись.


Подскажите, пожалуйста, что я неправильно делаю.
Записан
Zmeishe
Гость
« Ответ #1 : Ноябрь 14, 2008, 12:20 »

Не вдаваясь в детали,
ты пишешь в сокет и след. строкой говоришь deleteLater()  прибей его нах он мне не нужен.
Похоже сервер и не реагирует на то, что уже не актуально для клиента.
Лучше отключаться после того, как сервер вышлет подтверждение об успешном получении данных.
Записан
ритт
Гость
« Ответ #2 : Ноябрь 14, 2008, 14:13 »

млять! или форум глючит, или браузер Грустный
ррр...повторяю укороченный ответ:

Цитировать
bool QIODevice::waitForBytesWritten ( int msecs )   [virtual]
For buffered devices, this function waits until a payload of buffered written data has been written to the device and the bytesWritten() signal has been emitted, or until msecs milliseconds have passed. If msecs is -1, this function will not time out. For unbuffered devices, it returns immediately.
Returns true if a payload of data was written to the device; otherwise returns false (i.e. if the operation timed out, or if an error occurred).
This function can operate without an event loop. It is useful when writing non-GUI applications and when performing I/O operations in a non-GUI thread.

то, как делаешь ты сейчас, абсурдно, т.к. ты фактически прибиваешь сокет ещё ДО того, как с него были отправлены байты...
Записан
naico
Гость
« Ответ #3 : Ноябрь 14, 2008, 15:37 »

Оо, я понял, спасибо.
Я почему-то решил, что deleteLater будет ожидать записи в сокет и только после этого убьет этот самый сокет.Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.06 секунд. Запросов: 20.