sockets - QT QTcpServer::incomingConnection(qintptr handle) not firing? -
i'm trying create multithreaded server using qt first time. 1 use socket pointer returned qtcpserver::nextpendingconnection()
socket handle baked in - since i'm interfacing connecting client on separate thread, need create socket separately using qintptr handle
qtcpserver::incomingconnection(qintptr handle). after dreary, error-packed debugging session managed track down problem qtcpserver::incomingconnection()
never being fired?
has had similar problem - has changed on recent versions qt?
these ones i've tried:
qtcpserver::incomingconnection(qintptr handle)
qtcpserver::incomingconnection(qintptr socketdescriptor)
qtcpserver::incomingconnection(int handle)
edit:
creating instance of server:
testserver *myserver = new testserver(); myserver->initializeserver(1234);
which calls:
void testserver::initializeserver(quint16 port) { mainserver = new qtcpserver(this); mainserver->listen(qhostaddress::any, port); qdebug() << "listening connections on port: " << port; }
server listening. when client connects incomingconnection(qintptr handle) supposed called:
void testserver::incomingconnection(qintptr socketdescriptor){ testclient *client = new testclient(this); client->setsocket(socketdescriptor); }
which calls:
void testclient::setsocket(quint16 socketdescr) { socket = new qtcpsocket(this); socket->setsocketdescriptor(socketdescr); connect(socket, signal(connected()),this,slot(connected())); connect(socket, signal(disconnected()),this,slot(disconnected())); connect(socket, signal(readyread()),this,slot(readyread())); }
called on connect() signal:
void testclient::connected() { qdebug() << "client connected..."; // debug never appears in console, since qtcpserver::incomingconnection isn't being fired. }
you have errors @ code:
- at
testserver
qtcpserver
aggregated, need inherit it. @ case try overrideincomingconnection()
method, haven't base class , create newincomingconnection()
, not override. - you
qintptr descriptor
variableincomingconnection()
, setquint16
type @setsocket()
method. - you mix client of server , client of part, incoming connection , handling socket data.
i write little example below understanding tcp client-server communication.
server part
main part server themselves:
#include <qtcpserver> class testserver: public qtcpserver { public: testserver(qobject *parent = 0); void incomingconnection(qintptr handle) q_decl_override; };
just look: don't aggragate qtcpserver
, inherited it. @ case can override incomingconnection()
method correctly. @ constructor start server listening using listen()
method:
testserver::testserver(qobject *parent): qtcpserver(parent) { if (this->listen(qhostaddress::any, 2323)) { qdebug() << "server start @ port: " << this->serverport(); } else { qdebug() << "start failure"; } }
then time overriding incomingconnection()
:
void testserver::incomingconnection(qintptr handle) { qdebug() << q_func_info << " new connection"; socketthread *socket = new socketthread(handle); connect(socket, signal(finished()), socket, slot(deletelater())); socket->start(); }
i create socketthread
object handle incoming data:
#include <qthread> #include <qobject> class qtcpsocket; class socketthread: public qthread { q_object public: socketthread(qintptr descriptor, qobject *parent = 0); ~socketthread(); protected: void run() q_decl_override; private slots: void onconnected(); void onreadyread(); void ondisconnected(); private: qtcpsocket *m_socket; qintptr m_descriptor; };
we inherits qthread
making our server multithreading, have override run()
method:
socketthread::socketthread(qintptr descriptor, qobject *parent) : qthread(parent), m_descriptor(descriptor) { } void socketthread::run() { qdebug() << q_func_info; m_socket = new qtcpsocket; m_socket->setsocketdescriptor(m_descriptor); connect(m_socket, signal(readyread()), this, slot(onreadyread()), qt::directconnection); connect(m_socket, signal(disconnected()), this, slot(ondisconnected()), qt::directconnection); exec(); }
this way initialize our qtcpsocket
, set socket descriptor, connect readyread()
, disconnected()
signals , start event loop.
void socketthread::onreadyread() { qdatastream in(m_socket); in.setversion(qdatastream::qt_5_5); qstring message; in >> message; qdebug() << message; m_socket->disconnectfromhost(); } void socketthread::ondisconnected() { m_socket->close(); // exit event loop quit(); }
at onreadyread()
read qstring
client, write console , disconnect host. @ ondisconnected()
close socket connection , exit event loop.
client part
it example , bad-smells style, create connection server @ mainwindow
class on qpushbutton::clicked
signal:
void mainwindow::on_pushbutton_clicked() { qtcpsocket *client = new qtcpsocket; connect(client, signal(connected()), this, slot(connected())); connect(client, signal(disconnected()), client, slot(deletelater())); client->connecttohost(qhostaddress::localhost, 2323); client->waitforconnected(); if (client->state() != qabstractsocket::connectedstate ) { qdebug() << q_func_info << " can't connect host"; delete client; return; } qbytearray block; qdatastream out(&block, qiodevice::writeonly); out.setversion(qdatastream::qt_5_5); out << qstring("hello"); out.device()->seek(0); client->write(block); } void mainwindow::connected() { qdebug() << q_func_info << " client connected"; }
i create new qtcpsocket
, connect signals , try connect host(in case localhost). wait connected , check socket status. if right write socket qstring
- example.
it 1 of possible ways organized multithreading client-server architecture, hope helpfull , find yours bugs.
Comments
Post a Comment