Запись данных в TcpSocket в собственном потоке - PullRequest
4 голосов
/ 02 февраля 2011

У меня проблема с многопоточным TCP-сервером.
Я могу открыть свой сервер, создается новый сокет и я могу получать данные через сокет (я использовал сигнал readyRead (), а затем использовал readLine () для чтения, что работает нормально. Теперь я хочу записать данные в этот сокет из другого потока, поэтому я создал открытый слот writeData (), который должен об этом позаботиться. Я соединил слот writeData () с QueuedConnection (также пробовал AutoConnection), но все, что я получаю, когда вызываю m_socket-> write (), это ошибка сообщение:

QObject: Невозможно создать дочерние элементы для родителя, который находится в другом потоке. (Родитель - QNativeSocketEngine (0x12f0f70), родительский поток - ServerThread (0xfbbae8), текущий поток - QThread (0xfa7c48)

Вот лишь минимальный пример:
Я пропустил соединение из другого потока в слот writeData (), потому что я думаю, что каждый может себе это представить;)

class Server : public QTcpServer {
  Server();
protected:
  void incomingConnection(int socketDesc);
}

Server::Server() : QTcpServer() {
  this->listen(QHostAddress::Any, PORT);
}

void Server::incomingConnection(int socketDescriptor) {
  ServerThread *t = new ServerThread(socketDescriptor);
  t->start();
}

class ServerThread : public QThread {
  ServerThread(int socketDescriptor);
protected:
  void run();
public slots:
  void writeData(QString data);
private:
  int m_socketDescriptor;
  QTcpSocket *m_socket;
}

ServerThread::ServerThread(int socketDescriptor) : QThread(), m_socketDescriptor(socketDescriptor) {}

void ServerThread::run() {
  m_socket = new QTcpSocket();
  m_socket->setSocketDescriptor(m_socketDescriptor);
  exec();
}

void ServerThread::writeData(QString data) {
  m_socket->write(data.toAscii());
}

Заранее спасибо.

1 Ответ

5 голосов
/ 03 февраля 2011

Ваше сообщение об ошибке означает:

Ваше сообщение о слоте сигнала происходит на ServerThread экземпляре, который был создан и принадлежит основному потоку.Однако экземпляр ServerThread member m_socket был создан и принадлежит другому потоку.

Я бы предложил вам создать простой QThread и переместить в него ваш объект.

void Server::incomingConnection(int socketDescriptor) {
  QThread *t = new QThread();
  ClientConnection *client = new ClientConnection(socketDescriptor);
  client->moveToThread(t);

  // go
  t->start();
}

class ClientConnection : public QObject {
Q_OBJECT
public:
  ClientConnection(int socketDescriptor, QObject *parent = 0);
public slots:
  void writeData(QString data);
private:
  int m_socketDescriptor;
  QTcpSocket *m_socket;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...