0 / 0 / 0
Регистрация: 07.02.2022
Сообщений: 15
1

QTcpSocket SIGSEGV при попытке реконекта после краша сервера

08.02.2022, 22:40. Показов 1067. Ответов 7

Учу QT. Пытаюсь реализовать удалённое управление мышкой через телефон с помощью QTcpServer и QTcpSocket. Однако при реконекте выпадает SIGSEGV

Вот конструктор клиента:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_AcceptTouchEvents, true);
 
    socket = new QTcpSocket(this);
 
    connect(socket, &QTcpSocket::connected, this, &MainWindow::connectResived);
    connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);
    connect(socket, &QTcpSocket::disconnected, this, &MainWindow::disconnectResived);
}
По нажатии кнопки pushButton, вызывается этот слот:
C++ (Qt)
1
2
3
4
5
void MainWindow::on_pushButton_clicked()
{
    socket->connectToHost("192.168.31.193", 2323);
 
}
Последовательность действий такова:
Запускается сервер и клиент
жмём pushButton и подключаемся
Закрываем сервер
Запускаем сервер заново/не запускаем и жмём pushButton
SIGSEGV

В процессе гугления я наткнулся на это решение, однако то ли знаний в инглише не хватает, то ли знаний в qt, но я его не понял

Собственно я пытался сделать что либо при получении сигнала disconnected() но это ничего не изменило:
C++ (Qt)
1
2
3
4
5
6
void MainWindow::disconnectResived()
{
    socket->disconnectFromHost();
    //ну или
    QMetaObject::invokeMethod(m_socket, "connectToHost", Qt::QueuedConnection);
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.02.2022, 22:40
Ответы с готовыми решениями:

[Error SIGSEGV] Возникает ошибка при попытке присваивания
Есть 3 юнита: Первый - основной интерфейс программы Второй - интерфейс загрузки (тут ProgressBar)...

Исключение External SigSegv при попытке изменения компонента на другой форме
unit Unit2; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, Forms,...

Samsung Galaxy Ace s5831i не включается после краша Firefox
Внезапно при посещении сайта FF крашнулся, все зависло, и я решил его перезагрузить при помощи...

Зависание программы при попытке пинга сервера
Доброго времени суток, Написал программу для переделки обычного ПК с ОС Windows в некое подобие...

7
322 / 231 / 50
Регистрация: 29.05.2018
Сообщений: 663
09.02.2022, 00:27 2
А вот это пробовали (с той же ссылки стэковерфлоу):
For the ones who may come across with a similar situation, the reset method of the QTcpSocket solved the problem.
т.е. вот это:
C++ (Qt)
1
[virtual] bool QIODevice::reset()
?
0
2436 / 1176 / 435
Регистрация: 08.11.2016
Сообщений: 3,249
09.02.2022, 07:38 3
Лучший ответ Сообщение было отмечено BITniki как решение

Решение

у Вас в конструкторе клиента у сокета связан сигнал disconnected со слотом deleteLater, а значит при переходе сокета в состояние "отключен" он уничтожается и далее в своем слоте on_bushbutton_clicked Вы (при повторном подключении) разыменовываете уаазатель на разрушенный объект и получаете закономерный сегментэйшн фолт. Перенесите строки с созданием сокета и подключением сигналов из конструктора в слот on_button_clicked и вставьте их перед вызовом connectToHost.
2
1322 / 585 / 283
Регистрация: 02.05.2020
Сообщений: 1,409
09.02.2022, 09:31 4
А если после разрыва соединения и при удалении сокета создавать опять новый QTcpSocket?
0
2436 / 1176 / 435
Регистрация: 08.11.2016
Сообщений: 3,249
09.02.2022, 12:30 5
kapbepucm, похоже на подход проктолога в зубоврачебном кабинете, зачем создавать новый сокет при разрыве соединения? А если в дальнейшем соединение вовсе не будет устанавливаться вплоть до окончания работы программы, тогда вообще зачем содержать в памяти сконструированный сокет? Логичнее сконструировать сокет непосредственно перед установкой соединения. Хотя в данном конкретном случае вообще непонятно зачем создавать сокет в куче, уже куда лучше было бы объявить сокет непосредственным членом класса и отдать управление памятью на откуп непосредственно RAII и вместо связывания сигналов по deleteLater написать слот-обработчик для сигнала void QTcpSocket::stateChanged(QAbstractSocket::SocketState socketState), тем более что в текущем варианте, даже если перенести конструирование сокета и его связку с сигналами в слот-обработчик кнопки, то это хоть и уберет проблему с падение программы, но потенциально грозит утечкой памяти, так как если в ходе подключения к серверу произойдет какая-нибудь ошибка сокета, то сокет встанет в ошибку и выбросит stateChange, а disconnected так и не будет выброшен и сокет не будет удален, а при повторном нажатии на кнопку создастся новый сокет и перетрет старый указатель.
3
kapbepucm
09.02.2022, 13:35
  #6

Не по теме:

Annemesski, я невнимательно прочитал задание, почемуто решил, что речь идёт об автоматическом reconnect при обрыве связи :gsorry:

0
0 / 0 / 0
Регистрация: 07.02.2022
Сообщений: 15
09.02.2022, 16:51  [ТС] 7
kapbepucm, спасибо, ваш совет помог.

Цитата Сообщение от Annemesski Посмотреть сообщение
kapbepucm, Хотя в данном конкретном случае вообще непонятно зачем создавать сокет в куче, уже куда лучше было бы объявить сокет непосредственным членом класса и отдать управление памятью на откуп непосредственно RAII и вместо связывания сигналов по deleteLater написать слот-обработчик для сигнала void QTcpSocket::stateChanged(QAbstractSocket::SocketState socketState)
А можно поподробнее про это? Создание в куче это socket = new QTcpSocket(this);? Что значит объявить членом класса?
0
2436 / 1176 / 435
Регистрация: 08.11.2016
Сообщений: 3,249
09.02.2022, 16:56 8
Цитата Сообщение от BITniki Посмотреть сообщение
Создание в куче это socket = new QTcpSocket(this);?
Да, это оно. Память выделяемая вручную, выделяется в куче (грубо говоря в оперативной памяти).
Цитата Сообщение от BITniki Посмотреть сообщение
Что значит объявить членом класса?
Объявить членом класса объект типа QTcpSocket, а не указатель на него, тогда объект будет создан вместе с классом и уничтожен вместе с ним.
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.02.2022, 16:56
Помогаю со студенческими работами здесь

QTcpSocket автоматический опрос сервера
Есть сервер, который на запросы клиента генерит массив и отправляет ему обратно, клиент его...

Ошибка 401 при попытке отправить push c удаленного сервера
Делаю отправку уведомлений на андроид-приложение с сервера в GCM, пользуюсь GCMMessage...

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

При попытке загрузить данные из файла в базу данных сервера выдает ошибку -401 Unauthorize
Здравствуйте! Проект asp.net core 3.1, mvc. Пытаюсь загрузить данные из файла в базу данных...

Ошибка HTTP 500 (Internal Server Error): При попытке сервера выполнить запрос возникла неожиданная ситуация.
Есть ли ошибки в синтаксе? <?php if(!isset($_COOKIE)) { echo "<p>Здравствуйте, $_COOKIE<p>; }...

Http сервер и клиент. При попытке получить ответ клиента от сервера ошибка: Поток был недоступен для чтения
Здравствуйте, пытаюсь разобраться с написанием клиент-серверного приложения используя сокеты....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru