Сервер не принимает данные от клиента

314
01 июля 2017, 11:33

здравствуйте, пишу клиент-серверное приложение, в итоге для каждого соединения хочу брать поток из QThreadPool... это пока наброски, поэтому код соответствующий, однако сервер лишь посылает данные клиенту, но ничего не получает от него, хотя должен:

server.h:

#include <QTcpServer>
#include <QAbstractSocket>
#include <QTcpSocket>
#include <QThreadPool>
#include "tcpconnection.h"
void log_(const QString& msg);
class TcpServer_impl final : public QTcpServer {
  Q_OBJECT
public:
  explicit TcpServer_impl(QObject* parent = nullptr);
  ~TcpServer_impl();
Q_SIGNALS:
  void createConnection(quintptr descriptor);
protected:
  void incomingConnection(qintptr descriptor) override final;
};
class CServer final : public QObject {
  Q_OBJECT
public:
  CServer(std::size_t port, QObject *parent = nullptr);
  ~CServer();
  void listen();
  void stop();
  void reload();
  //void waitClients();
  void setMaxThreads(size_t n);
  std::size_t getPort() { return m_Port; }
  enum STATE {
    STATE_INIT = 0,
    STATE_STOPPED,
    STATE_STARTED,
    STATE_RELOADED
  };
public Q_SLOTS:
  // обработчик входного соединения
  void connection_handler(quintptr descriptor);
private:
  std::size_t m_Port = 0;
  STATE m_State;
//  QHash<int, QTcpSocket*> m_TcpClients;
//  Qhash<int, QLocalSocket*> m_USockClients;
  QHash<int, IConnection*> m_Connections;
  TcpServer_impl* m_Serv;
  QThreadPool* m_Pool;
};

server.cpp:

#include "server.h"
void log_(const QString &msg) {
  qDebug() << msg;
}
TcpServer_impl::TcpServer_impl(QObject *parent)
  : QTcpServer(parent)
{
}
TcpServer_impl::~TcpServer_impl() {
}
void TcpServer_impl::incomingConnection(qintptr descriptor) {
  emit createConnection(descriptor);
}
CServer::CServer(std::size_t port, QObject* parent)
  : QObject(),
    m_Port(port),
    m_Serv(new TcpServer_impl(this)),
    m_State(STATE_INIT),
    m_Pool(new QThreadPool(this))
{
  connect(m_Serv, &TcpServer_impl::createConnection, this, &CServer::connection_handler);
}
void CServer::setMaxThreads(std::size_t n) {
  m_Pool->setMaxThreadCount(n);
}
CServer::~CServer() {
  m_Serv->close();
}
void CServer::listen() {
  if(m_Serv->listen(QHostAddress::Any, m_Port))
  {
    log_("server is started");
    m_State = STATE_STARTED;
  } else {
    log_("Server: not started!");
    //_Exit(1);
  }
}
//void CServer::waitClients() {
//  //ждем минуту, если нет соединений то заново
//  while(!m_Serv->waitForNewConnection(60000))
//  {
//    int stop = 0;
//    int stop1 = 0;
//  }
//}
void CServer::connection_handler(quintptr descriptor) {
  if(m_State == STATE_STARTED) {
    IConnection* c = new CTcpConnection(descriptor, this);
    c->setAutoDelete(true);
    QThreadPool::globalInstance()->start(c);
    //m_Pool->start(c);
  }
}
void CServer::stop() {
}
void CServer::reload() {
}

connection.h:

#include <QThreadPool>
#include <QTcpSocket>
#include <QRunnable>
class IConnection : public QObject, public QRunnable{
  Q_OBJECT
public:
  IConnection(QObject* parent = nullptr);
  virtual ~IConnection();
protected:
  void run() = 0;
};
class CTcpConnection : public IConnection {
  Q_OBJECT
public:
  explicit CTcpConnection(qintptr _descriptor);
  CTcpConnection(qintptr _descriptor, QObject* parent);
  ~CTcpConnection();
public Q_SLOTS:
  void onRead();
  void onDisconnect();
  void onWrite(const QString& data);
protected:
  void run();
private:
  //QTcpSocket m_Sock;
  qintptr m_Descriptor;
};

connection.cpp:

#include "connection.h"
IConnection::IConnection(QObject *parent)
  : QObject(parent)
{
}
IConnection::~IConnection() {
}
CTcpConnection::CTcpConnection(qintptr _descriptor)
  : IConnection(),
    m_Descriptor(_descriptor)
{
}
CTcpConnection::CTcpConnection(qintptr _descriptor, QObject *parent)
  : IConnection(parent),
    m_Descriptor(_descriptor)
{
}
CTcpConnection::~CTcpConnection() {
  //m_Sock.close();
}
void CTcpConnection::onRead() {
}
void CTcpConnection::onWrite(const QString &data) {
}
void CTcpConnection::onDisconnect() {
//  m_Sock.close();
}
void CTcpConnection::run() {
  QTcpSocket m_Sock;
  //connect(&m_Sock, &QTcpSocket::readyRead, this, &CTcpConnection::onRead, Qt::DirectConnection);
  connect(&m_Sock, &QTcpSocket::readyRead, this, [&m_Sock]{
    std::cout << m_Sock.readAll().toStdString();
  }, Qt::DirectConnection);
  connect(&m_Sock, &QTcpSocket::disconnected, this, &CTcpConnection::onDisconnect, Qt::DirectConnection);
  m_Sock.setSocketDescriptor(m_Descriptor);
   //этот блок ничего не принимает
  //while(m_Sock.bytesAvailable()>0)
  //    {
  //        QByteArray array = m_Sock.readAll();
  //        std::cout<<array.toStdString()<<std::endl;
   //       m_Sock.write(array);
   //   }
  m_Sock.write("From server: hello world");
  m_Sock.flush();
}

client.cpp:

#include <QCoreApplication>
#include <QTcpSocket>
#include <QHostAddress>
#include <QDataStream>
#include <QObject>
#include <QThread>
#include <iostream>
int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);
  QTcpSocket *client = new QTcpSocket;
  QObject::connect(client, &QTcpSocket::connected, client, []{
    std::cout<<"connected!!!\n";
  });
  QObject::connect(client, &QTcpSocket::disconnected, client, &QTcpSocket::deleteLater);
  QObject::connect(client, &QTcpSocket::readyRead, [&client]{
    QByteArray arr = client->readAll();
    std::cout<< arr.toStdString() << std::endl;
  });
  client->connectToHost(QHostAddress::LocalHost, 1200);
  client->waitForConnected();
  if (client->state() != QAbstractSocket::ConnectedState ) {
      qDebug() << Q_FUNC_INFO << " can't connect to host";
      delete client;
  }
    QByteArray block;
//    QDataStream out(&block, QIODevice::WriteOnly);
//    out.setVersion(QDataStream::Qt_5_5);
//    out << QString("Hello, Server");
//    out.device()->seek(0);
//    client->write(block);
    client->write("Hello, Server");
  return a.exec();
}

В итоге клиент посылает данные, и сервер отправляет ему hello world, но от клиента ничего не принимает, т.е. сигнал readyRead не эмитится... подскажите в чем проблема

update: добавил к CTcpConnection два поля: QTcpSocket* m_Sock; QEventLoop* m_Loop; и изменил методы run и onRead:

void CTcpConnection::onRead() {
  std::cout << m_Sock->readAll().toStdString() << " " << QThread::currentThreadId();
  m_Sock->write("hello from server");
}
void CTcpConnection::run() {
  m_Loop = new QEventLoop();
  m_Sock = new QTcpSocket();
  //QTcpSocket m_Sock;
  connect(m_Sock, &QTcpSocket::readyRead, this, &CTcpConnection::onRead, Qt::DirectConnection);
  connect(m_Sock, &QTcpSocket::disconnected, this, &CTcpConnection::onDisconnect, Qt::DirectConnection);
  m_Sock->setSocketDescriptor(m_Descriptor);
  m_Loop->exec();
  delete m_Sock;
  delete m_Loop;
}

теперь заходим в метод onRead, однако ничего не выводится, но hello from server клиент принимает... в чем прикол?

update: поставил в метод onRead следующее:

qDebug << m_Sock->readAll().toStdString() << " " << QThread::currentThreadId(); 

и все стало выводится... вынес в деструктор CTcpConnect...

delete m_Sock; 
delete m_Loop; 

и не знаю насколько правильное вообще решение, что eventloop какой-то левый создается в методе run...

READ ALSO
Использование iostream_operator для записи в файл

Использование iostream_operator для записи в файл

Здравствуйте, я пытаюсь записать и прочитать созданный класс WRstrcut, используя ostream_iterator и istream_iteratorС записью проблем нет, а вот с чтением есть

277
Не компилится solidity

Не компилится solidity

Компилирую вот по этому мануВылетает такая ошибка:

269
C++ Почему не работает предварительное объявление класса?

C++ Почему не работает предварительное объявление класса?

Мне главное чтобы я мог из любого класса связаться с объектом любого другого класса (для этого я делаю наследование)Но запутался как правильно...

288
Как сделать, чтобы открытое миобильное slidemenu можно было скроллить?

Как сделать, чтобы открытое миобильное slidemenu можно было скроллить?

Добрый вечер, столкнулся с проблемойПытаюсь сделать, чтобы в мобильной версии страницы, при открытом slidemenu скроллилось оно, а не содержимое...

259