Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Qt и кроссплатформенное программирование С/С++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.03.2013, 17:15   #1
Last
В прострации
Форумчанин
 
Регистрация: 13.01.2009
Сообщений: 239
По умолчанию Threadedfortuneserver - добавить чтение клиентского сообщения.

Всем привет, суть проблемы в названии. В моей текущей реализации ответ клиенту приходит, но сервер сразу после этого падает. Отладчиком найти место падения не получается, т.к. оно происходит где-то в дизассемблированных кодах, в коих я ничего не понимаю.
Мой вариант thread.h:
Код:
class Thread : public QThread
{
  Q_OBJECT

public:
  Thread(int socketDescriptor, const QString &fortune, QObject *parent);
  void run();
  
signals:
  void error(QTcpSocket::SocketError socketError);
  
private:
  int socketDescriptor;
  QTcpSocket *tcpSocket;
  QString text;
  quint16 blockSize;

private slots:
  void readClient();
};
Кусок server.cpp:
Код:
void Server::incomingConnection(qintptr socketDescriptor)
{
  QString fortune = fortunes.at(qrand() % fortunes.size());
  Thread *thread = new Thread(socketDescriptor, fortune, this);
  connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
  thread->start();
}
И гвоздь программы - thread.cpp:
Код:
void Thread::run()
{
  tcpSocket = new QTcpSocket(NULL);
  if (!tcpSocket->setSocketDescriptor(socketDescriptor)) {
    emit error(tcpSocket->error());
    return;
  }
  blockSize = 0;
  connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readClient()));
  connect(tcpSocket, SIGNAL(disconnected()), tcpSocket, SLOT(deleteLater()));
  connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(quit()));
  tcpSocket->waitForDisconnected();
}

void Thread::readClient()
{
  QDataStream in(tcpSocket);
  in.setVersion(QDataStream::Qt_4_0);
  if (blockSize == 0) {
    if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
      return;
    in >> blockSize;
  }

  if (tcpSocket->bytesAvailable() < blockSize)
    return;
  in >> text;
  QByteArray block;
  QDataStream out(&block, QIODevice::WriteOnly);
  out.setVersion(QDataStream::Qt_4_0);
  out << (quint16)0;
  out << text;
  out.device()->seek(0);
  out << (quint16)(block.size() - sizeof(quint16));
  tcpSocket->write(block);
  tcpSocket->disconnectFromHost();
}
Ошибки из Application Output
Цитата:
QSocketNotifier: socket notifiers cannot be enabled from another thread
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNativeSocketEngine(0x12ba6e40), parent's thread is Thread(0x12ba80e0), current thread is QThread(0x12b3e0b0)
QSocketNotifier: socket notifiers cannot be disabled from another thread
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 12b3e0b0. Receiver '' (of type 'QNativeSocketEngine') was created in thread 12ba80e0", file kernel\qcoreapplication.cpp, line 420
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
QNativeSocketEngine::waitForWrite() was called on an uninitialized socket device
Я понимаю, что эти ошибки связаны с наличием tcpSocket'a в классе треда. У меня своего рода дилемма: если убрать tcpSocket из класса треда, то сигнал readyRead() вызовется один раз, после чего тред просто повиснет и клиент не получит ответа, а если tcpSocket не убирать, приложение вообще падает с ASSERT FAILURE.
Подскажите пожалуйста, если есть идеи, как можно выбраться из такой ситуации.
Пол-жизни сидючи, в монитор глядючи...
Last вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание клиентского приложения Hey4 JavaScript, Ajax 3 20.09.2011 00:35
Как добавить обработчик сообщения в класс iceman2112 Visual C++ 1 15.03.2011 18:00
Написание клиентского интерфейса Matthew Помощь студентам 1 10.01.2011 00:37
Взаимодействие клиентского приложения с сервером Assembler_1990 Java для Web (EE, Servlet, JSP, Tomcat, Spring MVC) 10 01.03.2010 13:36