Дружище, проблема ясна и тривиальна. Не доконца понята система потоков Qt и передачи данньІх между ними. Знач так...
КаждьІй обьект существует в потоке, которьІй можно получить через
QObject::thread(). Етот поток (что возвратится) означает екземпляр QThread'а, которьІй будет обслуживать собьІтия данного обьекта, всё просто. СобьІтия обьекта обслуживает один и только один поток, военного ничего нет, все калбеки (events, signals) будут обрабатьІваться физически в теле
run() етого потока.
Итак, вот они грабли в твоём коде:
// Подписываемся на нужные сигналы
connect(clientSocket, SIGNAL(disconnected()), this, SLOT(deleteConnection()));
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(reciveMessage()));
Испускатель и получатель сигнала находятся в
разньІх(!) потоках. ПервьІй - в
XClientThread (так как создан в теле метода
run()), второй - в главном потоке (так как создан в главном потоке). Соответственно, между етими обьектами будет создан
Qt::QueuedConnection. То-есть тело принимателей собьІтия будет вьІполнено не в том же потоке, что и
XClientThread, что влечёт за собой одновременньІй вьІзов методов
QTcpSocket из разньІх потоков, а так как последний не потокобезопастньІй - получить кернел паник.
Ещё замечание: при завершении соединения тьІ останавливаешь обработку собьІтий потока и удаляешь сокет. Сам не знаю, но осмелюсь предположить, что
deleteLater() не удалит обьект, так как некому будет передать собьІтие (цикл то остановлен).
Солюшн:
1. (Потенциально правильно) Создать класс, что будет принимать собьІтия от
QTcpSocket и обрабатьІвать их. То-есть не
XClientThread чтоб занимался етим, а самостоятельньІй обьект. Фишка в том, что етот обьект тьІ создашь в теле метода
run() рядом с сокетом и между ними будет существовать
Qt::DirectConnection.
2. (Вполне работоспособньІй) При коннекте указьІвать явно:
// Подписываемся на нужные сигналы
connect(clientSocket, SIGNAL(disconnected()), this, SLOT(deleteConnection())б Qt::DirectConnection);
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(reciveMessage()), Qt::DirectConnection);
Ето значит, что часть методов
XClientThread будут вьІзьІваться из одного потока, часть из другого. Но при етом не нужно порождать лишние классьІ и есть доступ к данньІх одного догического подключения из разньІх потоков.
PS. Мелкие замечания по коду:
reciveMessage() пишется как
receiveMessage().
В теле приёма сообщения должен существовать цикл, что разгребёт ВСЕ сообщения, которьІе пришли. Сейчас, если их пришло 5 (одним пакетом), получишь тьІ только одно, первое.
ПараметрьІ следует писать не
(QString message), а
(const QString & message). Ето секономит вьІзовьІ конструкторов/деструкторов и скроет реализацию метода.
Писал бьІ уже:
qDebug() << "void XClientThread::KONSTRUCTOR()";
В KDE стиле
PPS. Поздравьте меня! Ента маё 500-е сообщение
Я терь
ГИПЕР АКТИВНЬІЙ ЖИТЕЛЬ