2
votes

I am writing a client server program that server is multi thread , The code compile without any error, but it doesn't show any message from client. just it run up to the "qDebug() << " Client connected";" Here is my code .I would be grateful if you can say where is the problem.

myclient.cpp

#include "myclient.h"
#include "QTcpsocket"
#include "QTcpServer"
#include "mainwindow.h"
#include "QHostAddress"



myclient::myclient(QObject* parent): QObject(parent)
{
}

void myclient::start(QString address, quint16 port)
  {

       QHostAddress LocalHost;
       LocalHost.setAddress(address);

        m_client.connectToHost(LocalHost, 6666);

        QObject::connect(&m_client, SIGNAL(connected()),this, SLOT(startTransfer()));

   }

void myclient::startTransfer()
{
  m_client.write("Hello", 5);
}

mythread.cpp

#include "mythread.h"
#include "myserver.h"

mythread::mythread(QTcpSocket*, QObject *parent) :

QThread(parent)
{
}

void mythread::run()
{

  qDebug() << " Thread started";

    if (m_client)

  {
  connect(m_client, SIGNAL(connected()), this, SLOT(readyRead()), Qt::DirectConnection);
  }


 qDebug() << " Client connected";

     exec();
  }


void mythread::readyRead()

{
  QByteArray Data = m_client->readAll();

  qDebug()<< " Data in: " << Data;

  m_client->write(Data);
}


void mythread::disconnected()
{
  qDebug() << " Disconnected";

  m_client->deleteLater();

  exit(0);
}

myserver.cpp

#include "myserver.h"
#include "mythread.h"


myserver::myserver(QObject *parent) :

QObject(parent)
{
}

void myserver::startserver()
{

  connect(&m_server,SIGNAL(newConnection()), this ,SLOT(newConnection()));

  int port = 6666;

  if(m_server.listen(QHostAddress::Any, port))

  {        
    qDebug() << "Listening to port " ;
  }

 else
  {
    qDebug() << "Could not start server "<<m_server.errorString();
  }
  }


void myserver::newConnection()
{

 m_client = m_server.nextPendingConnection();

 qDebug() << " Connecting...";

 mythread *thread = new mythread(m_client,this);

 thread->start();

}
2
Please edit your question and add codes of your server.frogatto

2 Answers

1
votes

Documentation about nextPendingConnection() says:

Note: The returned QTcpSocket object cannot be used from another thread. If you want to use an incoming connection from another thread, you need to override incomingConnection().

So, you can't use that socket in another thread. As the docs say, you can subclass QTcpServer and override incomingConnection(), this method is invoked whenever a client tries to connect to your server.

incomingConnection() method provides a socket descriptor (just like regular file descriptors). And then you can pass that socket descriptor to another thread and create the QTcpSocket completely over there.

Inside that thread, you would need something like this:

QTcpSocket client = new QTcpSocket();
client.setSocketDescriptor(sockId);

// Now, you can use this socket as a connected socket.
// Make sure to connect its ready read signal to your local slot.
0
votes

Once you get in newConnection the client is already connected, and you just need to start a thread that calls readAll and then replies.

There's no need to wait for a connected() signal again.

EDIT

The QSocket class is designed to work asynchronously on the main thread, based on events. From the documentation:

Warning: QSocket is not suitable for use in threads. If you need to uses sockets in threads use the lower-level QSocketDevice class.