Results 1 to 4 of 4

Thread: Client-Server App: Clients stop receiving data when one client leaves

  1. #1
    Join Date
    Aug 2015
    Posts
    2
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Unhappy Client-Server App: Clients stop receiving data when one client leaves

    Hello, I am developing a client-server app with QTcpSocket and QTcpServer (right now I have to make a simple chat).
    I am testing my app in local network, where there is one server and 2 clients, one client connects to localhost (as it runs on the same machine with the server) and another to 192.168.0.1, server listens at port 25600

    Clients connect fine, server stores their QTcpSockets in QList and QMap and when info comes from one client, the server sends it to other clients. If changes happen on server, it sends info to all clients.

    Data transfer works fine, but when any client leaves the server, the following code is executed:

    Qt Code:
    1. void Server::Disconnected() // slot, connected to sockets
    2. {
    3. RemoveClient(qobject_cast<QTcpSocket*>(sender()));
    4. }
    5. void Server::RemoveClient(QTcpSocket* client)
    6. {
    7. QString nick = clients[client]; //clients is a QMap<QTcpSocket*, QString>
    8. //at this line client is removed from map and list, but I don't remember the exact code, I'm writing this post from other machine
    9. foreach(QTcpSocket* s, clientsRaw) //clientsRaw is a QList<QTcpSocket*>
    10. {
    11. //here I want to inform all other clients that participant called 'nick' left
    12. WriteMessage(DT_PLAYERLEFT, nick, s); // this method writes number of bytes to be written, data type and the string to the QTcpSocket
    13. //DT_PLAYERLEFT is const quint16 with value of 5
    14. }
    15. }
    To copy to clipboard, switch view to plain text mode 

    The nickname is valid, WriteMessage method works fine as it was tested when I transfered data with all clients online.
    But after this code, when I have only 1 client connected to server, the data coming TO client is some junk, while data coming FROM client is read fine. The client code which handles incoming data is valid, but the incoming data after another client's leave does'nt even have meaningful data type. What did I do wrong?

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Client-Server App: Clients stop receiving data when one client leaves

    I would be checking very carefully that the QList of sockets contains the same sockets as the keys of the QMap, and that they are correctly maintained in parallel. (I would consider not having two lists in the first place)

    Check you do not have a null pointer in either list. Sender() and a cast can result in 0, and your remove code code can create a map entry with that pointer value (QMap::operator[]() will create default entries if the key does not exist).

    The "some junk" that is written may be result of logic errors or poor assumptions in the WriteMessage() function. What does it do if nick is empty? We cannot see that code.

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Client-Server App: Clients stop receiving data when one client leaves

    You are currently also writing data to the socket that has just disconnected, because it is still in the list when you iterate over it.

    Cheers,
    _

  4. #4
    Join Date
    Aug 2015
    Posts
    2
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Client-Server App: Clients stop receiving data when one client leaves

    I've removed QList and now use QMap::keys() for iterating through QTcpSockets. I checked the value that comes from sender() in debugger, it is not null and QMap does have such key entry. The iteration does not include the socket that have disconnected because before iterating I remove it from the list, checked that twice. The string to be sent is also not empty and valid (otherwise transmission is canceled). The server code appears to be fine, but somehow after client disconnection other QTcpSockets at server stop sending data as expected, only reading works fine.

    Here is the WriteMessage method code, just in case:

    Qt Code:
    1. void AbstractServer::WriteMessage(quint16 dataType, QString& s, QTcpSocket* socket)
    2. {
    3. if(s.isEmpty()) { return; }
    4. QByteArray block;
    5. QDataStream out(&block, QIODevice::WriteOnly);
    6. out.setVersion(QDataStream::Qt_4_0);
    7. out << dataType;
    8. out << (quint16)0;
    9. out << s;
    10. out.device()->seek((qint64)sizeof(quint16));
    11. out << (quint16)(block.size() - 2*sizeof(quint16));
    12. socket->write(block);
    13. while(socket->flush());
    14. socket->waitForBytesWritten(); //just in case
    15. }
    To copy to clipboard, switch view to plain text mode 

    Update: I've solved the problem, the client side did not recognise data type above 4 (silly me >_>). Thanks for help anyway!
    Last edited by SeriousAlexej; 16th August 2015 at 15:06.

Similar Threads

  1. Replies: 7
    Last Post: 20th May 2015, 09:28
  2. client sending data line by line to server in Qt
    By ajay in forum Qt Programming
    Replies: 3
    Last Post: 31st August 2012, 00:06
  3. Problem with TCP server/client (corrupted data)
    By chris15001900 in forum Qt Programming
    Replies: 5
    Last Post: 16th October 2011, 14:29
  4. server not getting client data
    By raj_iv in forum Qt Programming
    Replies: 0
    Last Post: 31st May 2011, 08:30
  5. Replies: 7
    Last Post: 10th May 2010, 11:26

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.