Results 1 to 18 of 18

Thread: Write to Threaded Server

  1. #1
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Write to Threaded Server

    Hello, i got stuck while trying writing to a threaded server. Receiving works fine but the other way around...
    Method readData() at tcpsocket.cpp is never called. What am I doing wrong?

    Server:

    Qt Code:
    1. MultiServer server;
    2. if (!server.listen(QHostAddress::Any, 15000)) {
    3. close();
    4. return;
    5. }
    To copy to clipboard, switch view to plain text mode 

    multiserver.cpp
    Qt Code:
    1. MultiServer::MultiServer(QObject *parent)
    2. : QTcpServer(parent)
    3. {
    4.  
    5. }
    6.  
    7. void MultiServer::incomingConnection(int socketDescriptor)
    8. {
    9. QString msg = "Message from server";
    10. ConnectionThread *thread = new ConnectionThread(socketDescriptor, msg, this);
    11. connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    12. thread->start();
    13. }
    To copy to clipboard, switch view to plain text mode 

    connectionthread.cpp
    Qt Code:
    1. ConnectionThread::ConnectionThread(int socketDescriptor, const QString &msg, QObject *parent)
    2. : QThread(parent)
    3. , socketDescriptor(socketDescriptor)
    4. , text(msg)
    5. {
    6.  
    7. }
    8.  
    9. void ConnectionThread::run()
    10. {
    11. my_sock = new CTcpSocket(socketDescriptor);
    12.  
    13. my_sock->writeData(text);
    14. }
    To copy to clipboard, switch view to plain text mode 

    tcpsocket.cpp
    Qt Code:
    1. CTcpSocket::CTcpSocket(int socketDescriptor, QObject *parent)
    2. : QObject(parent)
    3. , m_socketDescriptor(socketDescriptor)
    4. {
    5. m_tcpSocket = new QTcpSocket();
    6.  
    7. if (!m_tcpSocket->setSocketDescriptor(m_socketDescriptor)) {
    8. qDebug() << m_tcpSocket->error();
    9. return;
    10. }
    11.  
    12. [COLOR="Red"]connect(m_tcpSocket, SIGNAL(readyRead()), SLOT(readData()));[/COLOR]
    13. }
    14.  
    15.  
    16. [COLOR="Red"]void CTcpSocket::readData()
    17. {
    18. //ToDo Implement reading Data
    19. qDebug() << "try to read";
    20. //m_tcpSocket->waitForReadyRead(10000);
    21. }[/COLOR]
    22.  
    23.  
    24. void CTcpSocket::writeData(QString txt)
    25. {
    26. qDebug() << "try to write";
    27.  
    28. QByteArray block;
    29. QDataStream out(&block, QIODevice::WriteOnly);
    30. out.setVersion(QDataStream::Qt_4_0);
    31. out << (quint16)0;
    32. out << txt;
    33. out.device()->seek(0);
    34. out << (quint16)(block.size() - sizeof(quint16));
    35.  
    36. m_tcpSocket->write(block);
    37.  
    38. m_tcpSocket->waitForBytesWritten(10000);
    39.  
    40. m_tcpSocket->disconnectFromHost();
    41. m_tcpSocket->waitForDisconnected();
    42. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jul 2009
    Posts
    139
    Thanks
    13
    Thanked 59 Times in 52 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Write to Threaded Server

    Why do you call disconnectFromHost if you want a reply?

  3. #3
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Write to Threaded Server

    ohh sure - but i fixed it already - this i shouldn't do of course. But it doesn't work anyway :-?

    tcpsocket.cpp

    Qt Code:
    1. CTcpSocket::CTcpSocket(int socketDescriptor, QObject *parent)
    2. : QObject(parent)
    3. , m_socketDescriptor(socketDescriptor)
    4. {
    5. m_tcpSocket = new QTcpSocket();
    6.  
    7. if (!m_tcpSocket->setSocketDescriptor(m_socketDescriptor)) {
    8. qDebug() << m_tcpSocket->error();
    9. return;
    10. }
    11.  
    12. connect(m_tcpSocket, SIGNAL(readyRead()), SLOT(readData()));
    13. }
    14.  
    15.  
    16. void CTcpSocket::readData()
    17. {
    18. //ToDo Implement reading Data
    19. qDebug() << "try to read";
    20. //m_tcpSocket->waitForReadyRead(10000);
    21. }
    22.  
    23.  
    24. void CTcpSocket::writeData(QString txt)
    25. {
    26. qDebug() << "try to write";
    27.  
    28. QByteArray block;
    29. QDataStream out(&block, QIODevice::WriteOnly);
    30. out.setVersion(QDataStream::Qt_4_0);
    31. out << (quint16)0;
    32. out << txt;
    33. out.device()->seek(0);
    34. out << (quint16)(block.size() - sizeof(quint16));
    35.  
    36. m_tcpSocket->write(block);
    37.  
    38. m_tcpSocket->waitForBytesWritten(10000);
    39. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Write to Threaded Server

    One reason you're not being able to read is because there's nothing to read.
    Are you sure you are receiving data? Are you sure that what you send is correct?

  5. #5
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Write to Threaded Server

    There is something to read for sure - I've a working not threaded server. There the message arrives.

    Client is like this:

    Qt Code:
    1. InstructionGen::InstructionGen(..)
    2. {
    3. ...
    4. socket = new QTcpSocket(this);
    5. ...
    6. socket->connectToHost(server->text(), port->value());
    7. ...
    8. }
    9.  
    10. void InstructionGen::sendInstruction()
    11. {
    12. socket->write(prefix->text().toLatin1() + message->text().toLatin1() + "\n");
    13. log_stat->append((prefix->text().toLatin1() + message->text().toLatin1() + "\n").simplified());
    14. message->clear();
    15. }
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Write to Threaded Server

    Where do you call void InstructionGen::sendInstruction() in your server?

    Edit: and you don't need to use threads and the socket's blocking functions.

  7. #7
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Write to Threaded Server

    InstructionGen is the client, which should send data to the server.

    Thx for the hint with the blocking functions... but should work anyway - am I right?

  8. #8
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Write to Threaded Server

    You have lost me completely.
    Can you post the complete code please?

  9. #9
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Write to Threaded Server

    Okay: server is complete.

    Now the Client: its actual the ChatSample Client in a slightly different form.

    Client:

    main.cpp
    Qt Code:
    1. #include <QApplication>
    2. #include "instructiongen.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. InstructionGen generator;
    8. generator.show();
    9. return a.exec();
    10. }
    To copy to clipboard, switch view to plain text mode 

    instructiongen.cpp
    Qt Code:
    1. #include "instructiongen.h"
    2. #include <QVBoxLayout>
    3. #include <QHBoxLayout>
    4. #include <QGridLayout>
    5. #include <QPushButton>
    6. #include <QTextEdit>
    7. #include <QLabel>
    8. #include <QLineEdit>
    9. #include <QTcpSocket>
    10. #include <QBuffer>
    11. #include <QSpinBox>
    12. #include <QErrorMessage>
    13.  
    14. static const quint16 DEFAULT_PORT = 15001;
    15.  
    16. InstructionGen::InstructionGen(QWidget* parent, Qt::WFlags flags)
    17. : QWidget(parent, flags)
    18. {
    19. QVBoxLayout* main = new QVBoxLayout(this);
    20. QHBoxLayout* bottom = new QHBoxLayout;
    21.  
    22. QLabel* label = new QLabel("Server:", this);
    23. server = new QLineEdit(this);
    24. port = new QSpinBox(this);
    25. conn = new QPushButton("Connect", this);
    26. port->setRange(1, 32767);
    27. port->setValue(DEFAULT_PORT);
    28. server->setText("localhost");
    29. top->addWidget(label, 0, 0);
    30. top->addWidget(server, 0, 1);
    31. top->addWidget(port, 0, 2);
    32.  
    33. label = new QLabel("Prefix:", this);
    34. prefix = new QLineEdit(this);
    35. prefix->setText("sim.");
    36. top->addWidget(label, 1, 0);
    37. top->addWidget(prefix, 1, 1);
    38. top->addWidget(conn, 1, 2);
    39.  
    40. log_stat = new QTextEdit(this);
    41. log_stat->setReadOnly(true);
    42.  
    43. label = new QLabel("Instruction:", this);
    44. message = new QLineEdit(this);
    45. send = new QPushButton("Send", this);
    46. send->setDefault(true);
    47. bottom->addWidget(label);
    48. bottom->addWidget(message);
    49. bottom->addWidget(send);
    50.  
    51. main->addLayout(top);
    52. main->addWidget(log_stat);
    53. main->addLayout(bottom);
    54. setLayout(main);
    55.  
    56. buffer = new QBuffer(this);
    57. socket = new QTcpSocket(this);
    58. buffer->open(QIODevice::ReadWrite);
    59.  
    60. connect(message, SIGNAL(returnPressed()), SLOT(sendInstruction()));
    61. connect(send, SIGNAL(clicked()), SLOT(sendInstruction()));
    62. connect(conn, SIGNAL(clicked()), SLOT(toggleConnection()));
    63.  
    64. connect(socket, SIGNAL(connected()), SLOT(setConnected()));
    65. connect(socket, SIGNAL(disconnected()), SLOT(setDisconnected()));
    66. connect(socket, SIGNAL(readyRead()), SLOT(receiveMessage()));
    67.  
    68. setDisconnected();
    69. }
    70.  
    71. InstructionGen::~InstructionGen()
    72. {
    73. buffer->close();
    74. }
    75.  
    76. void InstructionGen::setConnected()
    77. {
    78. port->setEnabled(false);
    79. server->setEnabled(false);
    80. prefix->setEnabled(true);
    81. message->setEnabled(true);
    82. log_stat->setEnabled(true);
    83. log_stat->clear();
    84. send->setEnabled(true);
    85. conn->setText("Disconnect");
    86. }
    87.  
    88. void InstructionGen::setDisconnected()
    89. {
    90. port->setEnabled(true);
    91. server->setEnabled(true);
    92. prefix->setEnabled(false);
    93. message->setEnabled(false);
    94. log_stat->setEnabled(false);
    95. send->setEnabled(false);
    96. conn->setText("Connect");
    97. }
    98.  
    99. void InstructionGen::toggleConnection()
    100. {
    101. if (socket->state() == QAbstractSocket::UnconnectedState)
    102. {
    103. socket->connectToHost(server->text(), port->value());
    104. }
    105. else
    106. {
    107. socket->disconnectFromHost();
    108. }
    109. }
    110.  
    111. void InstructionGen::sendInstruction()
    112. {
    113. socket->write(prefix->text().toLatin1() + message->text().toLatin1() + "\n");
    114. log_stat->append((prefix->text().toLatin1() + message->text().toLatin1() + "\n").simplified());
    115. message->clear();
    116. }
    117.  
    118. void InstructionGen::receiveMessage()
    119. {
    120. // missing some checks for returns values for the sake of simplicity
    121. qint64 bytes = buffer->write(socket->readAll());
    122. // go back as many bytes as we just wrote so that it can be read
    123. buffer->seek(buffer->pos() - bytes);
    124. // read only full lines, line by line
    125. while (buffer->canReadLine())
    126. {
    127. QString line = buffer->readLine();
    128. log_stat->append("received: "+line.simplified());
    129. }
    130. }
    To copy to clipboard, switch view to plain text mode 

  10. #10
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Write to Threaded Server

    Here's your problem
    Qt Code:
    1. connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    To copy to clipboard, switch view to plain text mode 
    Do you understand why?

    If you want to keep it simple, I've just added an example to the wiki on how to do all this without using threads.
    A lot of people seem to think they need threads for some reason.
    http://www.qtcentre.org/wiki/index.p...ithout_threads

  11. The following user says thank you to tbscope for this useful post:

    Suncell (3rd June 2010)

  12. #11
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Write to Threaded Server

    Outsch yeah - thx.

    And I need to loop in the run method - right?

    Why isn't a thread necessary. The program will receive tons of data out of a medical device. It should be prevent in any case blocking biosignal analysis.
    Or doesn't it matter?

  13. #12
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: Write to Threaded Server

    You might want to have an event loop in your thread.

    Quote Originally Posted by Suncell View Post
    It should be prevent in any case blocking biosignal analysis
    And yet you use blocking functions :-)

    It doesn't really matter. In general, do not use threads for your connections. Do use them if you need to perform long tasks in parallel (send or receive a lot of data is not one of those tasks as it is received in packets).
    And if you don't use threads, don't use the blocking functions at all. Don't use them in threads either. The blocking functions are there for a few special cases where the client or server doesn't allow you to communicate asynchronously.

  14. #13
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Write to Threaded Server

    ^^ yeah I should remove them.

    But now - I'm still stuck. The readData() function is never called. Maybe deriving the Class CTcpSocket from QObject() is wrong?

    Now, server code looks like that:

    Server:

    Qt Code:
    1. MultiServer server;
    2. if (!server.listen(QHostAddress::Any, 15000)) {
    3. close();
    4. return;
    5. }
    To copy to clipboard, switch view to plain text mode 

    MultiServer.cpp
    Qt Code:
    1. MultiServer::MultiServer(QObject *parent)
    2. : QTcpServer(parent)
    3. {
    4.  
    5. }
    6.  
    7. void MultiServer::incomingConnection(int socketDescriptor)
    8. {
    9. QString msg = "Message from server";
    10. ConnectionThread *thread = new ConnectionThread(socketDescriptor, msg, this);
    11. thread->start();
    12. }
    To copy to clipboard, switch view to plain text mode 

    ConnectionThread.cpp
    Qt Code:
    1. ConnectionThread::ConnectionThread(int socketDescriptor, const QString &msg, QObject *parent)
    2. : QThread(parent)
    3. , socketDescriptor(socketDescriptor)
    4. , text(msg)
    5. {
    6.  
    7. }
    8.  
    9. void ConnectionThread::run()
    10. {
    11. my_sock = new CTcpSocket(socketDescriptor);
    12.  
    13. my_sock->writeData(text);
    14.  
    15. while(1)
    16. {
    17.  
    18. }
    19. }
    To copy to clipboard, switch view to plain text mode 

    tcpsocket.cpp
    Qt Code:
    1. CTcpSocket::CTcpSocket(int socketDescriptor, QObject *parent)
    2. : QObject(parent)
    3. , m_socketDescriptor(socketDescriptor)
    4. {
    5. m_tcpSocket = new QTcpSocket();
    6.  
    7. if (!m_tcpSocket->setSocketDescriptor(m_socketDescriptor)) {
    8. qDebug() << m_tcpSocket->error();
    9. return;
    10. }
    11.  
    12. connect(m_tcpSocket, SIGNAL(readyRead()), SLOT(readData()));
    13. }
    14.  
    15.  
    16. void CTcpSocket::readData()
    17. {
    18. //ToDo Implement reading Data
    19. qDebug() << "try to read";
    20. }
    21.  
    22.  
    23. void CTcpSocket::writeData(QString txt)
    24. {
    25. qDebug() << "try to write";
    26.  
    27. QByteArray block;
    28. QDataStream out(&block, QIODevice::WriteOnly);
    29. out.setVersion(QDataStream::Qt_4_0);
    30. out << (quint16)0;
    31. out << txt;
    32. out.device()->seek(0);
    33. out << (quint16)(block.size() - sizeof(quint16));
    34.  
    35. m_tcpSocket->write(block);
    36. }
    To copy to clipboard, switch view to plain text mode 

  15. #14
    Join Date
    Jul 2009
    Posts
    139
    Thanks
    13
    Thanked 59 Times in 52 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Write to Threaded Server

    Instead of "while (1)" which just loops forever and doesn't allow anything else to happen in that thread, yoiu need to run "exec()". This starts the event loop for a thread and will allow your events to run. Note, it is your responsibility to call "exit()" when you want event processing (and the thread) to finish.

  16. The following user says thank you to numbat for this useful post:

    Suncell (5th June 2010)

  17. #15
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Write to Threaded Server

    okay instead of while I use now exec(). Am I doing it right with the exit()?

    The connect works fine and also the reading of the incoming data.
    But writing to the socket by emitting a signal does not work - Cannot create children for a parent that is in a different thread - is the error. I tried moving several objects to several threads by using moveToThread(currentThread()). What should I move to which place?

    multiserver.cpp
    Qt Code:
    1. MultiServer::MultiServer(QObject *parent)
    2. : QTcpServer(parent)
    3. {
    4.  
    5. }
    6.  
    7. void MultiServer::incomingConnection(int socketDescriptor)
    8. {
    9. ConnectionThread *thread = new ConnectionThread(socketDescriptor, this);
    10. connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    11. thread->start();
    12. }
    To copy to clipboard, switch view to plain text mode 

    ConnectionThread.h
    Qt Code:
    1. #ifndef CONNECTIONTHREAD_H
    2. #define CONNECTIONTHREAD_H
    3.  
    4. #include <QThread>
    5. #include <QTcpSocket>
    6.  
    7. #include <QMutex>
    8. #include <QWaitCondition>
    9.  
    10. #include "tcpsocket.h"
    11.  
    12. class ConnectionThread : public QThread
    13. {
    14. Q_OBJECT
    15.  
    16. public:
    17. ConnectionThread(int socketDescriptor, QObject *parent);
    18. ~ConnectionThread();
    19.  
    20. void run();
    21.  
    22. void stop();
    23.  
    24. signals:
    25. void error(QTcpSocket::SocketError socketError, const QString &message);
    26. void dataAvailable(QString &msg);
    27.  
    28. private slots:
    29. void readData();
    30. void writeData(QString &msg);
    31.  
    32. private:
    33. int socketDescriptor;
    34. QString text;
    35.  
    36. QMutex mutex;
    37.  
    38. QBuffer* buffer;
    39.  
    40. QTcpSocket* m_tcpSocket;
    41. };
    42. #endif
    To copy to clipboard, switch view to plain text mode 

    ConnectionThread.cpp
    Qt Code:
    1. #include "ConnectionThread.h"
    2.  
    3. #include <QtNetwork>
    4.  
    5. ConnectionThread::ConnectionThread(int socketDescriptor, QObject *parent)
    6. : QThread(parent)
    7. , socketDescriptor(socketDescriptor)
    8. {
    9. qDebug() << currentThreadId ();//Thread Y
    10. }
    11.  
    12. ConnectionThread::~ConnectionThread ()
    13. {
    14. stop();
    15. }
    16.  
    17. void ConnectionThread::stop()
    18. {
    19. exit();
    20. }
    21.  
    22. void ConnectionThread::run()
    23. {
    24. qDebug() << currentThreadId();//Thread X - Different thread ID than all others
    25.  
    26.  
    27. m_tcpSocket = new QTcpSocket();
    28.  
    29. buffer = new QBuffer();
    30. buffer->open(QIODevice::ReadWrite);
    31.  
    32.  
    33. if (!m_tcpSocket->setSocketDescriptor(socketDescriptor)) {
    34. emit error(m_tcpSocket->error(), m_tcpSocket->errorString());
    35. return;
    36. }
    37.  
    38. connect(m_tcpSocket, SIGNAL(readyRead()), SLOT(readData()));
    39. connect(this, SIGNAL(dataAvailable(QString &)), SLOT(writeData(QString &)));
    40.  
    41. exec();
    42. }
    43.  
    44. void ConnectionThread::readData()
    45. {
    46. qDebug() << "data arrived";
    47. qDebug() << currentThreadId (); // Thread Y
    48.  
    49. qint64 bytes = buffer->write(m_tcpSocket->readAll());
    50. buffer->seek(buffer->pos() - bytes);
    51. while (buffer->canReadLine())
    52. {
    53. QString line = buffer->readLine();
    54. //log_stat->append("received: "+line.simplified());
    55. qDebug() << line;
    56. }
    57.  
    58. QString msg = "reply code";
    59.  
    60. emit dataAvailable(msg);//here is the Error -Cannot create children for a parent that is in a different thread - emitted
    61. }
    62.  
    63.  
    64. void ConnectionThread::writeData(QString &msg)
    65. {
    66. qDebug() << msg;
    67. qDebug() << currentThreadId (); //Thread Y
    68. qint64 blockSize = msg.size();
    69. m_tcpSocket->write(msg.toAscii().data(),blockSize);
    70. }
    To copy to clipboard, switch view to plain text mode 





    AND just for Information:
    Working version without signal and slots - but with a strict order of reading and writing

    ConnectionThread.cpp version 2
    Qt Code:
    1. #include "ConnectionThread.h"
    2.  
    3. #include <QtNetwork>
    4.  
    5. ConnectionThread::ConnectionThread(int socketDescriptor, QObject *parent)
    6. : QThread(parent)
    7. , socketDescriptor(socketDescriptor)
    8. {
    9. }
    10.  
    11.  
    12. void ConnectionThread::run()
    13. {
    14. while(1)// ToDo no quit
    15. {
    16. // int st;
    17. // switch(tcpSocket.state())
    18. // {
    19. // case QTcpSocket::UnconnectedState:
    20. // st= 0;
    21. // break;
    22. // case QTcpSocket::HostLookupState:
    23. // st= 1;
    24. // break;
    25. // case QTcpSocket::ConnectingState:
    26. // st= 2;
    27. // break;
    28. // case QTcpSocket::ConnectedState:
    29. // st= 3;
    30. // break;
    31. // case QTcpSocket::BoundState:
    32. // st= 4;
    33. // break;
    34. // case QTcpSocket::ListeningState:
    35. // st= 5;
    36. // break;
    37. // case QTcpSocket::ClosingState:
    38. // st= 6;
    39. // break;
    40. // }
    41. // qDebug() << st;
    42.  
    43.  
    44. while (tcpSocket.bytesAvailable() < (int)sizeof(quint16)) {
    45. if (!tcpSocket.waitForReadyRead(Timeout)) {
    46. qDebug() << "Nothing arrived!";
    47. if(tcpSocket.state()!=QTcpSocket::ConnectedState)
    48. {
    49. qDebug() << "Connection broken!";
    50. emit error(tcpSocket.error(), tcpSocket.errorString());
    51. return;
    52. }
    53. continue;
    54. }
    55. }
    56.  
    57. char *buffer = (char*) malloc (1024);
    58. quint64 n = tcpSocket.read(buffer,1024);
    59.  
    60.  
    61.  
    62. mutex.lock();
    63. QString txt = QString(buffer).mid(0,n);
    64.  
    65. qDebug() << txt;
    66.  
    67. //cond.wait(&mutex); //wait condition to wake up thread -> obsolete waiting above for data arriving - maybe connect with incoming data
    68.  
    69. mutex.unlock();
    70.  
    71.  
    72. QString msg = "Hello, world - here is rtproc! Give me some data to process! \n";//Todo just for debug purpose
    73. qint64 blockSize = msg.size();//Todo just for debug purpose
    74.  
    75. tcpSocket.write(msg.toAscii().data(),blockSize);//Todo just for debug purpose
    76. tcpSocket.flush();//Todo just for debug purpose
    77. }
    78.  
    79.  
    80. // tcpSocket.disconnectFromHost();
    81. // tcpSocket.waitForDisconnected();
    82. }
    To copy to clipboard, switch view to plain text mode 

  18. #16
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Write to Threaded Server

    Found a very useful thread in the forum: http://www.qtcentre.org/threads/1197...ded-TCP-server

    But writing to the client is now a problem....

    Code looks now like that:

    multiserver.cpp
    Qt Code:
    1. #include "multiserver.h"
    2.  
    3. MultiServer::MultiServer(QObject *parent)
    4. : QTcpServer(parent)
    5. {
    6. }
    7.  
    8. void MultiServer::incomingConnection(int socketDescriptor)
    9. {
    10. server = new ServerThread(socketDescriptor, this);
    11. connect(server, SIGNAL(finished()), server, SLOT(deleteLater()));
    12. server->start();
    13. }
    To copy to clipboard, switch view to plain text mode 

    serverthread.cpp
    Qt Code:
    1. #include "serverthread.h"
    2.  
    3. ServerThread::ServerThread(int socketDescriptor, QObject *parent)
    4. : QThread(parent)
    5. , m_socketDescriptor(socketDescriptor)
    6. {
    7. qDebug() << currentThreadId ();
    8. }
    9.  
    10. ServerThread::~ServerThread ()
    11. {
    12. stop();
    13. }
    14.  
    15. void ServerThread::stop()
    16. {
    17. exit();
    18. }
    19.  
    20. void ServerThread::run()
    21. {
    22. serverSocket = new ServerTcpSocket();
    23.  
    24. if (!serverSocket->setSocketDescriptor(m_socketDescriptor)) {
    25. emit error(serverSocket->error(), serverSocket->errorString());
    26. qDebug() << "setSocketDescriptor error : " << serverSocket->error() << endl;
    27. return;
    28. }
    29.  
    30. exec();
    31. }
    To copy to clipboard, switch view to plain text mode 

    servertcpsocket.cpp
    Qt Code:
    1. #include "servertcpsocket.h"
    2.  
    3. ServerTcpSocket::ServerTcpSocket(QObject *parent)
    4. : QTcpSocket(parent)
    5. {
    6. buffer = new QBuffer();
    7. buffer->open(QIODevice::ReadWrite);
    8.  
    9. connect(this, SIGNAL(readyRead()), this, SLOT(readData()));
    10.  
    11. connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
    12. }
    13.  
    14.  
    15. void ServerTcpSocket::readData()
    16. {
    17. qint64 bytes = buffer->write(this->readAll());
    18. buffer->seek(buffer->pos() - bytes);
    19. while (buffer->canReadLine())
    20. {
    21. QString line = buffer->readLine();
    22. qDebug() << line;
    23. }
    24.  
    25. emit dataAvailable();
    26. }
    To copy to clipboard, switch view to plain text mode 

    Any clue how to solve the writing to the client
    Last edited by Suncell; 6th June 2010 at 20:28.

  19. #17
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Write to Threaded Server

    Actually writing to the client does work, but with annoying messages.
    When I try to write a reply immediately after receiving a message. (For debug purpose it is solved with a connect.)
    Then I got always "QObject: Cannot create children for a parent that is in a different thread." But reply message is send anyway. So i could not care about, but its a kind of distrubing. This error appears with and without moving to thread. Is there a way to fix this problem?

    serverthread.cpp
    Qt Code:
    1. #include "serverthread.h"
    2.  
    3. ServerThread::ServerThread(int socketDescriptor, QObject *parent)
    4. : QThread(parent)
    5. , m_socketDescriptor(socketDescriptor)
    6. {
    7. qDebug() << currentThreadId ();
    8. }
    9.  
    10. ServerThread::~ServerThread ()
    11. {
    12. stop();
    13. }
    14.  
    15. void ServerThread::stop()
    16. {
    17. exit();
    18. }
    19.  
    20. void ServerThread::run()
    21. {
    22. serverSocket = new ServerTcpSocket();
    23.  
    24. if (!serverSocket->setSocketDescriptor(m_socketDescriptor)) {
    25. emit error(serverSocket->error(), serverSocket->errorString());
    26. qDebug() << "setSocketDescriptor error : " << serverSocket->error() << endl;
    27. return;
    28. }
    29.  
    30. connect(serverSocket, SIGNAL(dataAvailable()), this, SLOT(writeData()));
    31.  
    32. exec();
    33. }
    34.  
    35. void ServerThread::writeData()
    36. {
    37. serverSocket->moveToThread(currentThread());
    38. //QObject::moveToThread: Current thread (0x1b102fc0) is not the object's thread (0x1b01b6a0).
    39. //Cannot move to target thread (0x1b01b6a0)
    40.  
    41. m_mutex.lock();
    42.  
    43. QString msg = "Message from Server\n";
    44. qint64 blockSize = msg.size();
    45.  
    46. serverSocket->write(msg.toAscii().data(),blockSize);
    47. // QObject: Cannot create children for a parent that is in a different thread.
    48. //(Parent is QNativeSocketEngine(0x103df1b0), parent's thread is ServerThread(0x103c2910), current thread is QThread(0x101966a0)
    49. m_mutex.unlock();
    50. }
    To copy to clipboard, switch view to plain text mode 

  20. #18
    Join Date
    Jun 2010
    Posts
    13
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Smile Solved - maybe not nice but it works!!!

    Solved it finally!
    Now writing and reading are running in one different thread

    I'm thankful for every improvement.

    Now the Source code:
    multiserver.cpp
    Qt Code:
    1. #include "multiserver.h"
    2.  
    3. MultiServer::MultiServer(QObject *parent)
    4. : QTcpServer(parent)
    5. {
    6. }
    7.  
    8. MultiServer::~MultiServer()
    9. {
    10. delete server;
    11. }
    12.  
    13. void MultiServer::incomingConnection(int socketDescriptor)
    14. {
    15. qDebug() << "MultiServer thread " << QThread::currentThreadId ();
    16.  
    17. server = new ServerThread(socketDescriptor);
    18. connect(server, SIGNAL(finished()), server, SLOT(deleteLater()));
    19. server->start();
    20. }
    To copy to clipboard, switch view to plain text mode 

    serverthread.cpp
    Qt Code:
    1. #include "serverthread.h"
    2.  
    3. ServerThread::ServerThread(int socketDescriptor)
    4. , m_socketDescriptor(socketDescriptor)
    5. {
    6. QObject::moveToThread(this); //destroy the obsolete thread
    7. qDebug() << "ServerThread " << QThread::currentThreadId ();
    8. }
    9.  
    10. ServerThread::~ServerThread ()
    11. {
    12. stop();
    13. delete serverSocket;
    14. }
    15.  
    16. void ServerThread::stop()
    17. {
    18. this->quit();
    19. this->wait();
    20. }
    21.  
    22. void ServerThread::run()
    23. {
    24. serverSocket = new ServerTcpSocket();
    25.  
    26. if (!serverSocket->setSocketDescriptor(m_socketDescriptor)) {
    27. emit error(serverSocket->error(), serverSocket->errorString());
    28. qDebug() << "setSocketDescriptor error : " << serverSocket->error() << endl;
    29. return;
    30. }
    31.  
    32. connect(serverSocket, SIGNAL(dataAvailable()), this, SLOT(writeData()));
    33.  
    34. this->exec();
    35. }
    36.  
    37. void ServerThread::writeData()
    38. {
    39.  
    40. qDebug() << "writing thread" << currentThreadId ();
    41.  
    42. QString msg = "Message from Server\n";//Todo just for debug purpose
    43. qint64 blockSize = msg.size();//Todo just for debug purpose
    44.  
    45. serverSocket->write(msg.toAscii().data(),blockSize);
    46. }
    To copy to clipboard, switch view to plain text mode 

    servertcpsocket.cpp
    Qt Code:
    1. #include "servertcpsocket.h"
    2.  
    3. ServerTcpSocket::ServerTcpSocket(QObject *parent)
    4. : QTcpSocket(parent)
    5. {
    6. buffer = new QBuffer();
    7. buffer->open(QIODevice::ReadWrite);
    8.  
    9. connect(this, SIGNAL(readyRead()), this, SLOT(readData()));
    10.  
    11. connect(this, SIGNAL(disconnected()), this, SLOT(deleteLater()));
    12. }
    13.  
    14.  
    15. void ServerTcpSocket::readData()
    16. {
    17. qDebug() << "reading thread" << QThread::currentThreadId ();
    18. qint64 bytes = buffer->write(this->readAll());
    19. buffer->seek(buffer->pos() - bytes);
    20. while (buffer->canReadLine())
    21. {
    22. QString line = buffer->readLine();
    23. qDebug() << line;
    24. }
    25.  
    26. emit dataAvailable();
    27. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Simple Threaded Http Server
    By obi in forum Qt Programming
    Replies: 4
    Last Post: 20th October 2009, 10:42
  2. Network Threaded server problem
    By ^NyAw^ in forum Qt Programming
    Replies: 3
    Last Post: 23rd May 2008, 09:08
  3. Threaded TCP server
    By Sysace in forum Newbie
    Replies: 4
    Last Post: 21st February 2008, 12:37
  4. Threaded server.
    By nithinin2001 in forum Qt Programming
    Replies: 2
    Last Post: 15th November 2007, 16:37

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.