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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Не происходит событие QAbstractSocket::SocketError  (Прочитано 13683 раз)
xaleva
Гость
« : Январь 26, 2010, 11:29 »

Добрый день всем.Никак не могу поймать сигнал QAbstractSocket::SocketError.На одной из веток на этом форуме  http://www.prog.org.ru/topic_11560_0.html  нашел описание ситуации,подобной моей.Там все решалось при смене версии на 4.6,у меня это не помогает,вот отрывок кода:

Код:

    connect (_socket,SIGNAL (connected ()),this,SLOT (slotSocketConnected ()));
    connect (_socket,SIGNAL (readyRead ()),this,SLOT (slotSocketReadyRead ()));
    connect (_socket,SIGNAL (disconnected ()),this,SLOT (slotSocketDisconnected ()));
    connect (_socket,SIGNAL(error (QAbstractSocket::SocketError)),this,SLOT (slotSocketError (QAbstractSocket::SocketError)));
    _socket->connectToHost(ip,port,QIODevice::ReadWrite);
    _socket->waitForConnected (1000);

    if (_socket->state() == QAbstractSocket::UnconnectedState)
    {
        ......
    }


В документации есть такой вот момент  http://doc.crossplatform.ru/qt/4.3.2/qabstractsocket.html#error-2, попробывал прописать,все равно не помогло.Может кто-нибудь сталкивался с такой проблемой?
Записан
BRE
Гость
« Ответ #1 : Январь 26, 2010, 11:56 »

Если хочешь ловить сигналы, то откажись от _socket->waitForConnected (1000);
Код
C++ (Qt)
void ClassName::createConnection( ... )
{
_socket = new QTcpSocket(...);
connect (_socket,SIGNAL (connected ()),this,SLOT (slotSocketConnected ()));
connect (_socket,SIGNAL (readyRead ()),this,SLOT (slotSocketReadyRead ()));
connect (_socket,SIGNAL (disconnected ()),this,SLOT (slotSocketDisconnected ()));
connect (_socket,SIGNAL(error (QAbstractSocket::SocketError)),this,SLOT (slotSocketError (QAbstractSocket::SocketError)));
_socket->connectToHost(ip,port,QIODevice::ReadWrite);
}
 
и по вызовам сигналов будешь определять, что происходит (подключились, пришли данные, произошла ошибка).

И QAbstractSocket::SocketError нужно зарегестрировать в мета-системе.
« Последнее редактирование: Январь 26, 2010, 12:04 от BRE » Записан
xaleva
Гость
« Ответ #2 : Январь 26, 2010, 12:11 »

Сделал,теперь работает вроде,но при выдергивании шнура не срабатывает.А вообще должно ли?
Записан
Amigo_sa
Гость
« Ответ #3 : Январь 26, 2010, 12:14 »

Сделал,теперь работает вроде,но при выдергивании шнура не срабатывает.А вообще должно ли?
Я слышал, что в qt существует серьезные проблемы с возвращением ошибок связи. Проявляется, например, если во время http или ftp запроса выдернуть сетевой кабель. 1 мой знакомый писал троллям запрос по этому поводу и они обещали поправить к след. релизу.
Как вариант, в своем приложении я тупо делал таймер, который сбрасывается при любом сигнале dataTransferProgress или commandsDone. работает
Записан
xaleva
Гость
« Ответ #4 : Январь 26, 2010, 13:00 »

Так,щас заметил что слот срабатывает и при _socket->waitForConnected (1000);  ,когда сокет закрываю.
Однако при вытаскивании шнура события не происходит.А мне как раз нужно ловить это сообщение.Выдергивание шнура - думаю, самая распространенная трабла в моем случае

Вообще кто нить проверял,происходит ли какое нить событие типа дисконнект или один из ерроров когда plugged out ?
« Последнее редактирование: Январь 26, 2010, 13:13 от xaleva » Записан
BRE
Гость
« Ответ #5 : Январь 26, 2010, 13:19 »

Вообще кто нить проверял,происходит ли какое нить событие типа дисконнект или один из ерроров когда plugged out ?
enum QAbstractSocket::SocketError:
QAbstractSocket::NetworkError   An error occurred with the network (e.g., the network cable was accidentally plugged out).

Но вот отслеживается ли это постоянно - не уверен.
Возможно, это состояние определяется при одном из действий типа connectToHost.
Записан
xaleva
Гость
« Ответ #6 : Январь 26, 2010, 13:39 »

Да,я как раз про эту ошибку и говорю.Я ее обрабатываю,но она не происходит при вытаскивании шнура.Кстати,у меня есть тоже такое подозрение,что произойдет при каком нить действии.Сейчас попробую
Записан
xaleva
Гость
« Ответ #7 : Январь 26, 2010, 14:09 »

Хм...чтот не     происходит...я уже и  state обрабатываю..все равно при анплагин никакого события не происходит
Записан
BRE
Гость
« Ответ #8 : Январь 26, 2010, 14:11 »

Хм...чтот не     происходит...я уже и  state обрабатываю..все равно при анплагин никакого события не происходит
Возможно, на некоторых платформах это работает, а на некоторых нет.
Попробуй погуглить на эту тему и воспользоваться сервисами предлагаемыми конкретной ОС.
Записан
Amigo_sa
Гость
« Ответ #9 : Январь 26, 2010, 14:29 »

Вообще кто нить проверял,происходит ли какое нить событие типа дисконнект или один из ерроров когда plugged out ?

Проверял для ftp=соединений. не происходит
Записан
xaleva
Гость
« Ответ #10 : Январь 26, 2010, 14:35 »

Да,телнетом тоже пока чтот не начнешь посылать,не почувствует.Складывается ощущение,что зависит все таки от ос..в данный момент сижу на слакваре
Записан
xaleva
Гость
« Ответ #11 : Январь 26, 2010, 15:48 »

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

  # cat /proc/sys/net/ipv4/tcp_keepalive_time
  7200

  # cat /proc/sys/net/ipv4/tcp_keepalive_intvl
  75

  # cat /proc/sys/net/ipv4/tcp_keepalive_probes
  9
т.е 7200 сек кеепелайва)вощем проблема решена,всем спасибо Улыбающийся
Записан
xaleva
Гость
« Ответ #12 : Январь 27, 2010, 10:41 »

Для тех,кто наткнется на подобную траблу,замечу ,что проблема так просто не решается.Дело в том,что

Цитировать
net.ipv4.tcp_keepalive_time = 7200
Переменная определяет как часто следует проверять соединение, если оно
давно не используется. Значение переменной имеет смысл только для тех
сокетов, которые были созданы с флагом SO_KEEPALIVE.

После недолгих поисков находим способ установить SO_KEEPALIVE для моего сокета,а так же программно установить интервал tcp_keepalive_time
Код:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

....
// эти строки надо написать после того,как сокет перейдет в состояние конектед,потому как до этого setsockopt ругается на плохой дескриптор,что можно понять.
    int optval;
    socklen_t optlen = sizeof(optval);
    optval = 1;
    setsockopt(_socket->socketDescriptor(), SOL_SOCKET, TCP_KEEPIDLE, &optval, optlen);  // Это строкой я устанавливаю интервал tcp_keepalive_time  на 1 сек
    setsockopt(_socket->socketDescriptor(), SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);  //  этой строкой врубаю SO_KEEPALIVE

Вот здесь можно найти подробное описание функции setsockopt и ее свойств http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.commtechref/doc/commtrf2/setsockopt.htm
« Последнее редактирование: Январь 27, 2010, 10:44 от xaleva » Записан
SABROG
Гость
« Ответ #13 : Январь 27, 2010, 12:08 »

Проблема давно решена уже. Зачем придумывать велосипед? Большинство протоколов реализуют команды типа PING/PONG.
Записан
xaleva
Гость
« Ответ #14 : Январь 27, 2010, 12:16 »

Можно по подробнее?
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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