I am using QSslSockets with a QTcpServer to create a simple client/server 
program (is there a higher level API I could use instead?). I have subclassed 
QTcpServer to create my server side sockets as QSslSockets and call 
startServerEncryption(), but otherwise it is just a standard QTcpServer.

When a socket first connects to the server, I make the following connection:

connect(clientConnection, SIGNAL(disconnected()), clientConnection, 
SLOT(deleteLater()));

where clientConnection is the QSslSocket created by the QTcpServer. Later, when 
using the socket (again on the server), I have the following function to wait 
for data from the client:

 ////////////////////////////////////////////////////////////
/// \brief EZPCore::waitForResponseReady
/// \param socket
/// \param msec
/// \return true=data available, false=timeout/error
///
/// Documentation for QAbstractSocket "waitForReadyRead" says
/// "This function may fail randomly on Windows. Consider using the event loop 
and the readyRead()
/// signal if your software will run on Windows."
/// so that's what this function does.
bool EZPCore::waitForResponseReady(QSslSocket *socket,int msec){
    if(!socket || !socket->isValid() || !socket->isEncrypted() || 
socket->state()!=QAbstractSocket::ConnectedState)
        return false; //there is something wrong with the socket, no point in 
waiting.

    if(socket->bytesAvailable()>0)
        return true;//success! Bytes are available!

    QEventLoop wait;  //don't block other operations while waiting
    QTimer waitTimeout; //only wait a set length of time.
    waitTimeout.setSingleShot(true);

    connect(&waitTimeout,&QTimer::timeout,[&wait]{wait.exit(-1);});
    connect(socket,&QAbstractSocket::disconnected,[&wait]{wait.exit(-2);}); 
//catch if the socket closes while waiting.
    connect(socket,&QAbstractSocket::readyRead,[&wait]{wait.exit();}); //zero 
exit

    waitTimeout.start(msec);
    int result=wait.exec();
    waitTimeout.stop(); //stop the timer if it is still running (probably 
unneeded?)

    if(result<0)
        return false; //not connected or timeout

    //should only get here if result is 0, indicating readyRead signal received.

    //if we have bytes available, then return success (0), even if
    //we had a timeout
    if(socket->bytesAvailable()>0) //<--------We frequently crash here, UNLESS 
I don't call "deleteLater()" on disconnect???
        return true;
    return false; //no bytes available
}

many times this works flawlessly. However,  I am frequently getting a crash 
when I call bytesAvailable() on the socket at the end of above function - a 
crash that is resolved if I don't make the connection to "deleteLater" when the 
socket is established. This tells me that the socket is getting deleted during 
this event loop. What I don't understand is why?

- When I come into this function, I check for QAbstractSocket::ConnectedState 
on the socket, and return immediately if not connected, which should mean that 
the socket is still connected when this function starts.
- I connect the "disconnected" signal of this function up to exit the event 
loop with a non-zero status should the socket disconnect during the event loop 
(entirely possible, of course)
- The function returns immediately if the event loop exits with a non-zero 
status, and the only way for the event loop to exit with a zero status is for 
readyRead to be emitted.

As such, the only way for the crashing line of code to be executed should be 
for a) the socket to be in a connected state (otherwise the function wouldn't 
run), b) disconnected signal to NOT to be emitted during the event loop (so 
still connected), and c) the readyRead signal to be emitted. However, the 
crashing would indicate that the socket *is* being deleted during the event 
loop, which indicates that the socket is disconnecting. And yet I still get a 
readyRead signal?

Incidentally, If I connect the destroyed signal to the event loop exit, I *do* 
catch that. So I can see the socket being destroyed, but not being 
disconnected. So obviously I have an architecture issue here: the socket is 
closing and being destroyed while I am still trying to read from it. How can I 
fix this?

Other notes:

- The server is currently NOT multi-threaded. This will probably need to change 
at some point, but if I can't even get a basic single-threaded server running...
- The above function is not necessarily called on every socket, as many times I 
can simply use the asynchronous signal/slot mechanism rather than waiting. This 
is only used when I need to return a value from a function based on what I get 
back from the client.

-----------------------------------------------
Israel Brewster
Systems Analyst II
5245 Airport Industrial Rd
Fairbanks, AK 99709
(907) 450-7293
-----------------------------------------------

[cid:[email protected]]



[cid:[email protected]]







BEGIN:VCARD
VERSION:3.0
N:Brewster;Israel;;;
FN:Israel Brewster
ORG:Frontier Flying Service;MIS
TITLE:PC Support Tech II
EMAIL;type=INTERNET;type=WORK;type=pref:[email protected]
TEL;type=WORK;type=pref:907-450-7293
item1.ADR;type=WORK;type=pref:;;5245 Airport Industrial Wy;Fairbanks;AK;99701;
item1.X-ABADR:us
CATEGORIES:General
X-ABUID:36305438-95EA-4410-91AB-45D16CABCDDC\:ABPerson
END:VCARD
_______________________________________________
Interest mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to