здравствуйте, пишу клиент-серверное приложение, в итоге для каждого соединения хочу брать поток из 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...
Виртуальный выделенный сервер (VDS) становится отличным выбором
Здравствуйте, я пытаюсь записать и прочитать созданный класс WRstrcut, используя ostream_iterator и istream_iteratorС записью проблем нет, а вот с чтением есть
Мне главное чтобы я мог из любого класса связаться с объектом любого другого класса (для этого я делаю наследование)Но запутался как правильно...
Добрый вечер, столкнулся с проблемойПытаюсь сделать, чтобы в мобильной версии страницы, при открытом slidemenu скроллилось оно, а не содержимое...