Связь QTcpSocket в потоке

Я делаю два приложения: одно - сервер, а другое - клиент. Сервер использует QTcpServer и QThread для прослушивания клиента. Клиент использует QThread для подключения к серверу. Сервер и клиент успешно соединились, но проблема заключается в том, как передать данные между ними. На стороне сервера я поставил строку для отправки данных клиенту с помощью socket->write("hello"), когда новый клиент подключен, но клиент не получил их. Гипотеза «не получил», основанная на том, что ничего не написано о вызове QDebug на стороне клиента. Кроме того, я хочу спросить о том, как сделать клиентский поток всегда готовым к получению данных с сервера, но иногда его можно использовать для отправки данных на сервер при использовании кнопки. Любая помощь будет оценена.

клиентская сторона main.cpp (с использованием виджета)

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "tcpthread.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    TcpThread *tcpThread = new TcpThread(this);
    connect(tcpThread, SIGNAL(finished()), tcpThread, SLOT(deleteLater()));
    tcpThread->start();
}

клиентская сторона tcpthread.h

#ifndef TCPTHREAD_H
#define TCPTHREAD_H

#include <QThread>
#include <QTcpSocket>

class TcpThread : public QThread
{
    Q_OBJECT
public:
    explicit TcpThread(QObject *parent = 0);
    void run();
signals:
    void error(QTcpSocket::SocketError socketError);
public slots:
    void readyRead();
    void disconnected();
private:
    void processMessage(QByteArray message);
    QTcpSocket *socket;
    qintptr socketDescriptor;
    QByteArray data;
};

#endif // TCPTHREAD_H

клиентская сторона tcpthread.cpp

#include "tcpthread.h"

TcpThread::TcpThread(QObject *parent) :
    QThread(parent)
{
}

void TcpThread::run()
{
    qDebug() << "Thread started";
    socket = new QTcpSocket();
    connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
    connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    socket->connectToHost("127.0.0.1",1234);
    exec();
}

void TcpThread::readyRead()
{
    data = socket->readAll();
    while(!data.contains('\n'))
    {
        socket->waitForReadyRead();
        data += socket->readAll();
    }
    int bytes = data.indexOf('\n')+1;
    QByteArray message = data.left(bytes);
    data = data.mid(bytes);
    qDebug() << socketDescriptor << " : " << message;
    processMessage(message);
}

void TcpThread::disconnected()
{
    qDebug() << socketDescriptor << " disconnected";
    socket->deleteLater();
    exit(0);
}

void TcpThread::processMessage(QByteArray message)
{
    qDebug() << message << " processed";
}

серверная сторона main.cpp

#include "tcpserver.h"
#include <QCoreApplication>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    TcpServer tcpServer;
    tcpServer.startServer();

    return a.exec();
}

серверная часть tcpthread.h

#ifndef TCPTHREAD_H
#define TCPTHREAD_H

#include <QThread>
#include <QTcpSocket>
#include <QDebug>

class TcpThread : public QThread
{
    Q_OBJECT
public:
    explicit TcpThread(qintptr ID, QObject *parent = 0);
    void run();
signals:
    void error(QTcpSocket::SocketError socketError);
public slots:
    void readyRead();
    void disconnected();
private:
    void processMessage(QByteArray message);
    QTcpSocket *socket;
    qintptr socketDescriptor;
    QByteArray data;
};

#endif // TCPTHREAD_H

серверная часть tcpthread.cpp #include "tcpthread.h"

TcpThread::TcpThread(qintptr ID, QObject *parent) :
    QThread(parent)
{
    this->socketDescriptor = ID;
}

void TcpThread::run()
{
    qDebug() << "Thread started";
    socket = new QTcpSocket();
    if(!socket->setSocketDescriptor(this->socketDescriptor))
    {
        emit error(socket->error());
        return;
    }
    connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
    connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    qDebug() << socketDescriptor << " connected";
    socket->write("hello");
    exec();
}

void TcpThread::readyRead()
{
    data = socket->readAll();
    while(!data.contains('\n'))
    {
        socket->waitForReadyRead();
        data += socket->readAll();
    }
    int bytes = data.indexOf('\n')+1;
    QByteArray message = data.left(bytes);
    data = data.mid(bytes);
    qDebug() << socketDescriptor << " : " << message;
    processMessage(message);
    //socket->write(data);
}

void TcpThread::disconnected()
{
    qDebug() << socketDescriptor << " disconnected";
    socket->deleteLater();
    exit(0);
}

void TcpThread::processMessage(QByteArray message)
{
    qDebug() << message << " processed";
}

person Kuzunoha    schedule 22.12.2013    source источник
comment
Я попытался скомпилировать код, вставленный выше, но не смог, потому что он неполный. В частности, для обеих программ не предусмотрена функция main().   -  person Jeremy Friesner    schedule 22.12.2013
comment
Проверяли ли вы errorString()/error(), когда не могли получить данные на стороне клиента, то есть после вызовов readAll()?   -  person lpapp    schedule 22.12.2013
comment
В чем причина вызова exec() в методах запуска?   -  person lpapp    schedule 22.12.2013
comment
Джереми Фриснер: Я отредактирую свой вопрос; Ласло Папп: Я не совсем понимаю, но это из учебника по ссылка   -  person Kuzunoha    schedule 22.12.2013
comment
Что касается серверной части, у меня есть ответ, демонстрирующий приемы, которые вы могли бы использовать, и еще один, который соответствует общему подходу.   -  person Kuba hasn't forgotten Monica    schedule 24.12.2013