Hello again,
I have been digging trough the QT documentation and found the problem. since i was using the standard Qtcpserver class with each new connection i used QTcpServer::nextPendingConnection which gives a QTcpSocket pointer. Now when setting a socketdescriptor the doc gives:
Note: It is not possible to initialize two abstract sockets with the same native socket descriptor.
so when opening a connection i used this:
QTcpSocket *sock = server->nextPendingConnection
To copy to clipboard, switch view to plain text mode
and started another thread passing the descriptor of the socket:
client = new incomingclientsession(&db, sock->socketDescriptor(), &mutex);
client = new incomingclientsession(&db, sock->socketDescriptor(), &mutex);
To copy to clipboard, switch view to plain text mode
In the thread i was creating another QTcpSocket and set the descriptor to the one that was given, This was probably the cause of not being able to read the socket.
My current code look like this:
Server class derives from QTcpServer where i override some functions:
{
Q_OBJECT
public:
tcpserver();
int nextConnection();
bool hasPendingConnections(); // Override
private:
QList<int> connections; // List to store pending connections (not sure if this is the right way)
protected:
void incomingConnection(int handle); // Override
};
class tcpserver : public QTcpServer
{
Q_OBJECT
public:
tcpserver();
int nextConnection();
bool hasPendingConnections(); // Override
private:
QList<int> connections; // List to store pending connections (not sure if this is the right way)
protected:
void incomingConnection(int handle); // Override
};
To copy to clipboard, switch view to plain text mode
The incommingConnection function will store the connection in the list and emit the newConnection signal instead of creating a QTcpSocket and adding that to the list.
void tcpserver::incomingConnection(int handle)
{
connections.append(handle);
emit this->newConnection();
}
void tcpserver::incomingConnection(int handle)
{
connections.append(handle);
emit this->newConnection();
}
To copy to clipboard, switch view to plain text mode
with this i can connect the signal and slot like this:
connect(serv, SIGNAL(newConnection()), this, SLOT(newsession()));
connect(serv, SIGNAL(newConnection()), this, SLOT(newsession()));
To copy to clipboard, switch view to plain text mode
where the slot looks like this":
void clienthandler::newsession() // Now i dont need to create a QTcpSocket to get the descriptor
{ // the nextConnection function of my QtcpServer class returns
QThread *t;
// the descriptor directly incomingslientsession *client;
while (serv->hasPendingConnections()){
client = new incomingslientsession(&db, serv->nextConnection(), &mutex);
connect(t, SIGNAL(started()), client, SLOT(dowork()));
connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); // Delete thread after session is handeled
client->moveToThread(t);
t->start();
}
}
void clienthandler::newsession() // Now i dont need to create a QTcpSocket to get the descriptor
{ // the nextConnection function of my QtcpServer class returns
QThread *t; // the descriptor directly
incomingslientsession *client;
while (serv->hasPendingConnections()){
t = new QThread();
client = new incomingslientsession(&db, serv->nextConnection(), &mutex);
connect(t, SIGNAL(started()), client, SLOT(dowork()));
connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); // Delete thread after session is handeled
client->moveToThread(t);
t->start();
}
}
To copy to clipboard, switch view to plain text mode
as you can see in the above code i dont have to work with any QTcpSocket to pass the socket to another thread.
in the thread i can now use the descriptor to open a QtcpSocket and read it like this:
void incomingslientsession::dowork()
{
qDebug
("Session handler thread id: %d",
(int) QThread::currentThreadId());
sock.setSocketDescriptor(sockfd); // Create socket directly from desciptor, reading and writing stuff to socket works fine now
while (sock.bytesAvailable() < 20) { // First 20 header bytes
if (!sock.waitForReadyRead()) {
qDebug("Disconnected");
qDebug() << sock.error();
return;
}
}
// Do stuff with data here
void incomingslientsession::dowork()
{
qDebug("Session handler thread id: %d", (int) QThread::currentThreadId());
QTcpSocket sock;
sock.setSocketDescriptor(sockfd); // Create socket directly from desciptor, reading and writing stuff to socket works fine now
while (sock.bytesAvailable() < 20) { // First 20 header bytes
if (!sock.waitForReadyRead()) {
qDebug("Disconnected");
qDebug() << sock.error();
return;
}
}
// Do stuff with data here
To copy to clipboard, switch view to plain text mode
this code works as it should and does not give me any debug messages about the sockets not being handeled in the right way. I'm quite interested in what you think i was doing wrong in the earlier code so if you could explain?
Thank you,
Sisco
Bookmarks