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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Взаимодействие по локалке  (Прочитано 4035 раз)
SibBear
Гость
« : Апрель 06, 2013, 20:35 »

Добрый день. Есть программа, установленная на нескольких компьютерах, которая следит за состоянием оборудования. Как средствами Qt сделать так, чтобы программа в определенных случаях отсылала сообщение своим копиям, которые, в свою очередь, выводили бы сообщение? Проблема в том, что локалка нестабильна и часто падает. Требуется проверять состояние раз в несколько секунд. Очень желательно, чтобы в случае отсутствия сети программа знала об этом мгновенно, а не пыталась подключиться в течение 30-40 секунд. Спасибо.
P.S. В сетевых делах ничего не соображаю, дайте направление, куда копать.
« Последнее редактирование: Апрель 06, 2013, 20:38 от SibBear » Записан
Странник
Гость
« Ответ #1 : Апрель 06, 2013, 21:46 »

просили направление - пожалуйста.
http://en.wikipedia.org/wiki/Keepalive
поищите в документации QAbstractSocket::KeepAliveOption.
« Последнее редактирование: Апрель 06, 2013, 21:51 от Странник » Записан
SibBear
Гость
« Ответ #2 : Апрель 06, 2013, 21:57 »

Спасибо!
« Последнее редактирование: Апрель 06, 2013, 22:01 от SibBear » Записан
Bepec
Гость
« Ответ #3 : Апрель 08, 2013, 15:44 »

Присоединюсь к вопросу.

Задача похожая - проверять доступность клиентов.

Бьюсь со связкой QTcpServer - QTcpSocket.

Socket корректно отрабатывает разрыв связи и пытается переподключаться.

Сервер же абсолютно игнорирует уже принятые соединения.

Попытка при newConnection вязать сокет с слотами ошибок и изменения состояний = бесполезно.

К тому же keepAlive вроде по умолчанию с таймаутом на 2 часа...

PS дежа вю. Я такую тему раньше не создавал?

update: Быстрый поиск дал http://www.prog.org.ru/topic_15945_0.html. Буду копать завтра. О результатах отпишусь.
« Последнее редактирование: Апрель 08, 2013, 15:49 от Bepec » Записан
Странник
Гость
« Ответ #4 : Апрель 08, 2013, 16:11 »

К тому же keepAlive вроде по умолчанию с таймаутом на 2 часа...
настройка таймаутов потребует написания нескольких строк платформозависимого кода для каждой из целевых платформ.
Записан
Bepec
Гость
« Ответ #5 : Апрель 09, 2013, 08:13 »

Спасибо за подсказку, по ссылке приведённой ранее уже имеется решение Веселый

Действительно, нужно писать платформозависимый код.

Под windows:
Код:
// подключаем Ws2_32.lib в проект (иначе будут unresolved'ы)

#include <winsock2.h> // библиотека работы с портами

// не нашёл константы на msdn. Кому интересно привожу ссылку
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd877220(v=vs.85).aspx. Видимо часть библиотеки windows. :)
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)


// собственно сама управляющая структура
struct tcp_keepalive {
u_long onoff; // включение /отключение
u_long keepalivetime; // время жизни
u_long keepaliveinterval; // время повторного запроса.
};


// этот кусок уже внутри слота connected(). Выполняется только при уже установленном подключении.
{
    //  pClientSocket - заменить на ваш QTcpSocket
    DWORD dwError = 0L,dwBytes ;
    tcp_keepalive pClSock_tcpKeepalive={0}, sReturned = {0};

    // заполняем структуру
    pClSock_tcpKeepalive.onoff=1;//включить keepalive
    pClSock_tcpKeepalive.keepalivetime=1000;// каждую "1.000" секунду отсылать пакет
    pClSock_tcpKeepalive.keepaliveinterval=1500;// Если не пришел ответ выслать через 1.5с повторно

    if (WSAIoctl(pClientSocket->socketDescriptor(), SIO_KEEPALIVE_VALS, &pClSock_tcpKeepalive,
    sizeof(pClSock_tcpKeepalive), &sReturned, sizeof(sReturned), &dwBytes,
    NULL, NULL) != 0)
    {
    dwError = WSAGetLastError() ;
    qWarning((char*)dwError);
    }
}

PS сделано на основании выкладки Orfus. Оригинал http://www.prog.org.ru/topic_15945_0.html.

PPS если начинает материться после включения winsock2.h, значит где-то ранее подключена windows.h и они конфликтуют.

Лечится включение только winsock2.h (он тянет за собой windows.h) или же #define WIN32_LEAN_AND_MEAN, который разруливает эту ситуацию.
« Последнее редактирование: Апрель 09, 2013, 08:16 от Bepec » Записан
Странник
Гость
« Ответ #6 : Апрель 09, 2013, 10:59 »

POSIX версия в общих чертах выглядит примерно так. Windows тоже имеет реализацию setsockopt, но на практике не проверял.
Код
#include <sys/socket.h>
#include <netinet/tcp.h>
 
void setKeepAlive(int socketDescriptor, int state, int idle, int interval)
{
  setsockopt(socketDescriptor, SOL_SOCKET, SO_KEEPALIVE, (void*)&state, sizeof(state));
  setsockopt(socketDescriptor, SOL_TCP, TCP_KEEPIDLE, (void*)&idle, sizeof(idle));
  setsockopt(socketDescriptor, SOL_TCP, TCP_KEEPINTVL, (void*)&interval, sizeof(interval));
}
где state == 0 - отключить keepalive, 1 - включить
idle - время простоя соединения перед началом отправки keepalive-пакетов
interval - время задержки между keepalive-пакетами
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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