Results 1 to 5 of 5

Thread: QLocalServer with multiple clients — proper handling

  1. #1
    Join Date
    Sep 2009
    Posts
    10
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Unhappy QLocalServer with multiple clients — proper handling

    I'm trying to make IPC work between one server to accept requests from multiple clients with Qt 4.6. All is working, except that the underlying named pipes are not being closed, making Qt to emit the maximum handle reached message (62).

    Since I want to accept several client connections, I handle newConnections to the QLocalServer class as follows:

    Qt Code:
    1. void ServerImpl::onNewConnection()
    2. {
    3. QLocalSocket * plsocket = _server->nextPendingConnection();
    4. SocketHandler* skh = new SocketHandler(plsocket, this, this);
    5. connect(plsocket, SIGNAL(readyRead()), skh, SLOT(socketReadyRead()));
    6. connect(plsocket, SIGNAL(error(QLocalSocket::LocalSocketError)), skh,
    7. SLOT(onError(QLocalSocket::LocalSocketError)));
    8. connect(plsocket, SIGNAL(disconnected()), skh, SLOT(disconnected()));
    9. }
    To copy to clipboard, switch view to plain text mode 

    Since every time I get a new connection the QLocalSocket pointer received from QLocalServer::nextPendingConnection() is overwritten, I manage the data requests through the SocketHandler class, which of course encapsulates a QLocalSocket class:

    Qt Code:
    1. void SocketHandler::socketReadyRead()
    2. {
    3. QDataStream in(_ps);
    4. in.setVersion(QDataStream::Qt_4_5);
    5.  
    6. forever
    7. {
    8. if (_blocksize == 0)
    9. {
    10. if (_ps->bytesAvailable() < sizeof(blocksize_t))
    11. return;
    12.  
    13. in >> _blocksize;
    14. }
    15.  
    16. // We need more data?
    17. if (_ps->bytesAvailable() < _blocksize)
    18. return;
    19.  
    20. _srv->ReadRequest(in);
    21.  
    22. // CHECK: Discard remaining blocks
    23. _blocksize = 0;
    24. }
    25. }
    To copy to clipboard, switch view to plain text mode 

    Here's the class declaration:

    Qt Code:
    1. class SocketHandler : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. SocketHandler(QLocalSocket* ps, ServerImpl* srv, QObject* parent = 0) :
    7. QObject(parent), _ps(ps), _blocksize(0), _srv(srv) { };
    8.  
    9. virtual ~SocketHandler() {};
    10.  
    11. public slots:
    12. void socketReadyRead();
    13. void onError(QLocalSocket::LocalSocketError);
    14. void disconnected();
    15.  
    16. private:
    17.  
    18. QLocalSocket* _ps;
    19. blocksize_t _blocksize;
    20. ServerImpl* _srv;
    21. };
    To copy to clipboard, switch view to plain text mode 

    The problem, as stated above, is that I can't disconnect from server at client request. I tried QLocalSocket::close, QLocalSocket::disconnectFromServer without luck.

    Should I go with a multithreaded solution? (I think it won't solve the problem).

    Another solution I'm thinking is to offer a 1:1 QLocalServer<-->QLocalSocket IPC mechanism, instead of trying to handle 1:N.

    Thanks in advance.

  2. #2
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: QLocalServer with multiple clients — proper handling

    Create a QLocalServer
    Inside the server, create a list of sockets (to keep track of them)
    Connect a slot to the newConnection() signal
    In that slot, go through the pending connections and add them to the list.
    Connect slots to the most important signals of the socket (like disconnected(), readyRead() etc... This can be done via a QSignalMapper
    Implement those slots (example, when disconnected, take the socket out of the list)

    That's it.

  3. #3
    Join Date
    Sep 2009
    Posts
    10
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QLocalServer with multiple clients — proper handling

    I think your approach is well thought, altough I don't find the difference with my multiple instances of a handler class (SocketHandler) except that it's not a socket (it does not inherit QLocalSocket) but QLocalSocket is composited as a member variable.

    I believe it's not related to the disconnection (and pipe-handle leaking) problem, but who cares, I will try your idea.

  4. #4
    Join Date
    Sep 2009
    Posts
    10
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QLocalServer with multiple clients — proper handling

    I implemented your solution, but I still keep getting pipe handles not closed.

    For each connection, Qt creates the following named pipes:

    Qt Code:
    1. \Device\NamedPipe\Win32Pipes.00001490.0000000X
    2. \Device\NamedPipe\<SERVER_KEY>
    To copy to clipboard, switch view to plain text mode 

    The second that includes the server key in the pipe name is the type of pipe handles that are not closing.

    May be it's an error in my client.
    When my client tries to shutdown the connection, the socket error slot signals, with:

    QLocalSocketPrivate::completeAsyncRead: Connection error

    My client application calls _socket->disconnectFromServer() in the aboutToQuit() handler slot (prior to app quitting).

    I related the problem to the eventloop not already responding on the aboutToQuit(), but I tried on other program sections, when the event loop is well alive, and it didn't work. Nevertheless, sockets will get deleted on clean program close, so I think I should not bother manually disconnecting.

  5. #5
    Join Date
    Sep 2009
    Posts
    10
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QLocalServer with multiple clients — proper handling



    Fixed by letting the server-side closing the socket on disconnection signal. The client just does not nothing, just waits the server to close and delete the QLocalSocket pointer on disconnection.

    Thanks, anyway.

Similar Threads

  1. Proper handling "Cancel" click for QWizard
    By Splinter in forum Qt Programming
    Replies: 4
    Last Post: 17th September 2012, 14:34
  2. Replies: 7
    Last Post: 10th May 2010, 11:26
  3. Extend QTcpServer to handle multiple clients
    By DiamonDogX in forum Qt Programming
    Replies: 5
    Last Post: 24th February 2010, 19:49
  4. Handling multiple forms
    By msmihai in forum Qt Programming
    Replies: 4
    Last Post: 6th December 2008, 13:41
  5. Handling multiple UDP sockets
    By ecphora in forum Qt Programming
    Replies: 2
    Last Post: 1st April 2006, 20:01

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.