Results 1 to 4 of 4

Thread: deleting TcpSocket pointer from QList on server when disconnecting

  1. #1
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default deleting TcpSocket pointer from QList on server when disconnecting

    I've got a server that every time a new connection comes in, the pointer to that socket is added to a struct which is added to a QList. The socket is actually part of a struct, but I don't' think that makes a difference. When the socket deletes, I want to remove the struct from my list so that my list of structs doesn't end up with a bunch of empty holes in it but still delete the socket properly. I don't want any dangling pointers. It seems to work, but if I don't have it right, it might cause memory leaks and I don't want that. If it was a normal pointer I would know what to do, but with sockets, timing matters (I think?)
    Qt Code:
    1. //.h
    2. struct struct_ClientSocket
    3. {
    4. QTcpSocket *pClientSocket;
    5. QString str_ClientAddress;
    6. int nPort;
    7. };
    8.  
    9. private:
    10. QList<struct_ClientSocket> m_lst_pClientSockets;
    11.  
    12. private slots:
    13. void SetIncomingSocket();
    14. void OnSocketDisconnected();
    15. void ReadInputData();
    16.  
    17. //.cpp
    18. void CKeyboardLogAdmin::SetIncomingSocket()
    19. {
    20. QStringList str_lst_Name;
    21. QTcpSocket *tempSocket = pTcpServer->nextPendingConnection();
    22. struct_ClientSocket temp_struct_ClientSocket;
    23. temp_struct_ClientSocket.pClientSocket = tempSocket;
    24. temp_struct_ClientSocket.str_ClientAddress = tempSocket->peerAddress().toString();
    25. temp_struct_ClientSocket.nPort = tempSocket->peerPort();
    26. connect(tempSocket, SIGNAL(disconnected()), tempSocket, SLOT(deleteLater()));
    27. connect(tempSocket, SIGNAL(disconnected()), this, SLOT(OnSocketDisconnected()));
    28. connect(tempSocket, SIGNAL(readyRead()), this, SLOT(ReadInputData()));
    29. m_lst_pClientSockets.append(temp_struct_ClientSocket);
    30. }
    31.  
    32. void CKeyboardLogAdmin::OnSocketDisconnected()
    33. {
    34. struct_ClientSocket tempSocket;
    35. for (int nSock = 0; nSock < m_lst_pClientSockets.size(); nSock++)
    36. {
    37. if (m_lst_pClientSockets[nSock].pClientSocket->state() == QAbstractSocket::UnconnectedState || m_lst_pClientSockets[nSock].pClientSocket->state() == QAbstractSocket::ClosingState)
    38. {
    39. m_lst_pClientSockets.removeAt(nSock);
    40. break;
    41. }
    42. }
    43. }
    44.  
    45. void CKeyboardLogAdmin::ReadInputData()
    46. {
    47. m_str_ReadData.clear();
    48. QByteArray ba_ByteData;
    49. int nSocket;
    50. if (m_lst_pClientSockets.size() > 0)
    51. {
    52. for (nSocket = 0; nSocket < m_lst_pClientSockets.size(); nSocket++)
    53. {
    54. if (m_lst_pClientSockets[nSocket].pClientSocket->bytesAvailable() > 0)
    55. {
    56. break;
    57. }
    58. }
    59. if (nSocket < m_lst_pClientSockets.size())
    60. {
    61. while (m_lst_pClientSockets[nSocket].pClientSocket->bytesAvailable() > 0)
    62. {
    63. ba_ByteData = m_lst_pClientSockets[nSocket].pClientSocket->readAll();
    64. }
    65. const char* ch_Data = ba_ByteData.data();
    66. m_str_ReadData = QString(ch_Data);
    67. QStringList str_lst_ReadData = m_str_ReadData.split("\t");
    68. if (!str_lst_ReadData.isEmpty())
    69. {
    70. if (str_lst_ReadData.first().compare(tr("LoginUser")) == 0)
    71. {
    72. ProcessLoginUserData(str_lst_ReadData);
    73. }
    74. if (str_lst_ReadData.first().compare(tr("LoginGuests")) == 0)
    75. {
    76. ProcessLoginGuests(str_lst_ReadData);
    77. }
    78. else if (str_lst_ReadData.first().compare(tr("Logout")) == 0)
    79. {
    80. ProcessLogoutData(str_lst_ReadData);
    81. }
    82. else if (str_lst_ReadData.first().compare(tr("ScreenLock")) == 0)
    83. {
    84. ProcessScreenLockData((str_lst_ReadData));
    85. }
    86. else if (str_lst_ReadData.first().compare(tr("ScreenUnlock")) == 0)
    87. {
    88. ProcessScreenUnlockData(str_lst_ReadData);
    89. }
    90. else if (str_lst_ReadData.first().compare(tr("AccountLogout")) == 0)
    91. {
    92. ProcessComputerUserAccountLogoutData(str_lst_ReadData);
    93. }
    94. else if (str_lst_ReadData.first().compare(tr("ValidatePin")) == 0)
    95. {
    96. ProcessValidatePinData(str_lst_ReadData);
    97. }
    98. else if (str_lst_ReadData.first().compare(tr("SessionLogoff")) == 0)
    99. {
    100. ProcessSessionLogoff(str_lst_ReadData);
    101. }
    102. }
    103. }
    104. }
    105. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by TonyInSoMD; 6th August 2018 at 20:18. Reason: updated contents added variable to .h file

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: deleting TcpSocket pointer from QList on server when disconnecting

    I would swap lines 22 and 23; connections are executed in the order they are made, so it would be best to ensure your disconnection cleanup code is executed prior to calling deleteLater() on the socket instance.

    You might also find QPointer or QSharedPointer useful to avoid dangling references. You can also connect to the QObject::destroyed() signal instead of disconnect().
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Mar 2014
    Location
    USA
    Posts
    85
    Thanks
    17
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: deleting TcpSocket pointer from QList on server when disconnecting

    Is something like this what you were talking about?

    Qt Code:
    1. //.h
    2. struct struct_ClientSocket
    3. {
    4. QTcpSocket *pClientSocket;
    5. QString str_ClientAddress;
    6. int nPort;
    7. };
    8.  
    9. private:
    10. QList<struct_ClientSocket> m_lst_pClientSockets;
    11.  
    12. private slots:
    13. void SetIncomingSocket();
    14. void OnSocketDestroyed();
    15. void ReadInputData();
    16.  
    17. //.cpp
    18. void CKeyboardLogAdmin::SetIncomingSocket()
    19. {
    20. QStringList str_lst_Name;
    21. QTcpSocket *tempSocket = pTcpServer->nextPendingConnection();
    22. struct_ClientSocket temp_struct_ClientSocket;
    23. temp_struct_ClientSocket.pClientSocket = tempSocket;
    24. temp_struct_ClientSocket.str_ClientAddress = tempSocket->peerAddress().toString();
    25. temp_struct_ClientSocket.nPort = tempSocket->peerPort();
    26. connect(tempSocket, SIGNAL(destroyed(QObject*)), this, SLOT(OnSocketDestroyed(QObject*)));
    27. connect(tempSocket, SIGNAL(disconnected()), tempSocket, SLOT(deleteLater()));
    28. connect(tempSocket, SIGNAL(readyRead()), this, SLOT(ReadInputData()));
    29. m_lst_pClientSockets.append(temp_struct_ClientSocket);
    30. }
    31.  
    32.  
    33.  
    34.  
    35. void CKeyboardLogAdmin::OnSocketDestroyed(QObject *obj)
    36. {
    37. for (int nSock = 0; nSock < m_lst_pClientSockets.size(); nSock++)
    38. {
    39. if (m_lst_pClientSockets[nSock].pClientSocket == obj)
    40. {
    41. m_lst_pClientSockets.removeAt(nSock);
    42. break;
    43. }
    44. }
    45. }
    46.  
    47.  
    48.  
    49.  
    50. void CKeyboardLogAdmin::ReadInputData()
    51. {
    52. m_str_ReadData.clear();
    53. QByteArray ba_ByteData;
    54. int nSocket;
    55. if (m_lst_pClientSockets.size() > 0)
    56. {
    57. for (nSocket = 0; nSocket < m_lst_pClientSockets.size(); nSocket++)
    58. {
    59. if (m_lst_pClientSockets[nSocket].pClientSocket->bytesAvailable() > 0)
    60. {
    61. break;
    62. }
    63. }
    64. if (nSocket < m_lst_pClientSockets.size())
    65. {
    66. while (m_lst_pClientSockets[nSocket].pClientSocket->bytesAvailable() > 0)
    67. {
    68. ba_ByteData = m_lst_pClientSockets[nSocket].pClientSocket->readAll();
    69. }
    70. const char* ch_Data = ba_ByteData.data();
    71. m_str_ReadData = QString(ch_Data);
    72. QStringList str_lst_ReadData = m_str_ReadData.split("\t");
    73. if (!str_lst_ReadData.isEmpty())
    74. {
    75. if (str_lst_ReadData.first().compare(tr("LoginUser")) == 0)
    76. {
    77. ProcessLoginUserData(str_lst_ReadData);
    78. }
    79. if (str_lst_ReadData.first().compare(tr("LoginGuests")) == 0)
    80. {
    81. ProcessLoginGuests(str_lst_ReadData);
    82. }
    83. else if (str_lst_ReadData.first().compare(tr("Logout")) == 0)
    84. {
    85. ProcessLogoutData(str_lst_ReadData);
    86. }
    87. else if (str_lst_ReadData.first().compare(tr("ScreenLock")) == 0)
    88. {
    89. ProcessScreenLockData((str_lst_ReadData));
    90. }
    91. else if (str_lst_ReadData.first().compare(tr("ScreenUnlock")) == 0)
    92. {
    93. ProcessScreenUnlockData(str_lst_ReadData);
    94. }
    95. else if (str_lst_ReadData.first().compare(tr("AccountLogout")) == 0)
    96. {
    97. ProcessComputerUserAccountLogoutData(str_lst_ReadData);
    98. }
    99. else if (str_lst_ReadData.first().compare(tr("ValidatePin")) == 0)
    100. {
    101. ProcessValidatePinData(str_lst_ReadData);
    102. }
    103. else if (str_lst_ReadData.first().compare(tr("SessionLogoff")) == 0)
    104. {
    105. ProcessSessionLogoff(str_lst_ReadData);
    106. }
    107. }
    108. }
    109. }
    110. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: deleting TcpSocket pointer from QList on server when disconnecting

    Something like that should work. I don't think there was anything wrong with your original solution (after lines swapped); I was just suggesting alternative ways to skin the same cat.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. The following user says thank you to d_stranz for this useful post:

    TonyInSoMD (7th August 2018)

Similar Threads

  1. Replies: 1
    Last Post: 17th December 2010, 09:53
  2. deleting invalid pointer
    By hollowhead in forum General Programming
    Replies: 11
    Last Post: 30th April 2010, 11:47
  3. TCPSocket/Server
    By TheGrimace in forum Qt Programming
    Replies: 20
    Last Post: 31st August 2009, 23:38
  4. deleting internal pointer in QModelIndex
    By rickbsgu in forum Qt Programming
    Replies: 18
    Last Post: 24th December 2008, 03:24
  5. Replies: 15
    Last Post: 6th April 2008, 11:06

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