Results 1 to 11 of 11

Thread: QTcpSocket/QTcpServer on a heavy load server

  1. #1
    Join Date
    Aug 2012
    Posts
    8
    Thanks
    1

    Default QTcpSocket/QTcpServer on a heavy load server

    Hello, I am designing and making a server that should be able to handle about 100+ hits per second. The information I am getting from the server is just the HTTP header. Based on the information from the header, it will query a database(different thread) for some information and send the final information back to the QTcpServer which create an output string, and send back a HTTP Response. I am having a big problem with this that I cannot debug. My code look similar to this:

    Qt Code:
    1. TCPInterface::TCPInterface(QObject *parent): QTcpServer(parent)
    2. {
    3. //start listening for tcp traffic on port 80
    4. listen(QHostAddress::Any, 80);
    5.  
    6. connect(this,SIGNAL(sendInfo(QTcpSocket*, QString *)), databaseThread, SLOT(recieveInfo(QTcpSocket*, QString*)));
    7. connect(databaseThread, SIGNAL(sendToTCPSend(QTcpSocket *, QString *)), this, SLOT(TCPSend(QTcpSocket*, QString*)));
    8.  
    9. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void TCPInterface::incomingConnection(int socket)
    2. {
    3. QTcpSocket *s = new QTcpSocket(this);
    4.  
    5. connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
    6. // connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
    7.  
    8. s->setSocketDescriptor(socket);
    9. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. //void TCPInterface::discardClient()
    2. //{
    3. // QTcpSocket* socket = (QTcpSocket*)sender();
    4. // socket->deleteLater();
    5. //}
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void TCPInterface::readClient()
    2. {
    3. QTcpSocket* socket = (QTcpSocket*)sender();
    4.  
    5. QString header;
    6. while(socket->canReadLine())
    7. {
    8. header += socket->readLine();
    9. }
    10.  
    11. emit sendInfo(socket, headerInfo);
    12. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void databaseThread::recieveInfo(QTcpSocket* socket, QString* headerInfo)
    2. {
    3. QString*outputInfo = getDatabaseInfo(headerInfo);
    4. emit sendToTCPSend(socket, outputInfo);
    5. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void TCPInterface::TCPSend(QTcpSocket* socket, QString* outputInfo);
    2. {
    3. QString response = "HTTP/1.0 200 Ok\r\n";
    4. response += "Content-Type: text/html; charset=\"utf-8\"\r\n";
    5. response += "\r\n" + *outputInfo + "\n";
    6.  
    7. if(socket->isWritable() && socket->isOpen())
    8. {
    9. socket->write(response.toAscii());
    10. }
    11. //socket->disconnectFromHost();
    12. socket->close();
    13. delete headerInfo;
    14. }
    To copy to clipboard, switch view to plain text mode 

    I having one main problem which I have an idea what it is, but cannot find a solution to fix it.

    My problem is my memory is constantly increasing as I get more hits. I am sure the cause of this is my QTcpSockets are never being deleted, since I am just closing them. However when I don't use close, and use disconnectFromHost and disconnected/discardClient slot/signal my server will crash with heavy traffic(no message or anything so I am not sure of the exact reason of the crash). Has anyone run into this problem before? Any ideas at all.

  2. #2
    Join Date
    May 2012
    Posts
    136
    Thanks
    2
    Thanked 27 Times in 24 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QTcpSocket/QTcpServer on a heavy load server

    I think the problem is that you try to delete the socket when it is not ready sending/receiving data
    connect to the signal disconnected() of the QTcpSocket use disconnectFromHost() to initiate the disconnect.
    then when the signal is fired disconnect the signal and kill the QTcpSocket

  3. #3
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket/QTcpServer on a heavy load server

    Side note to StrikeByte's. Kill them using QObject::deleteLater.
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  4. #4
    Join Date
    Aug 2012
    Posts
    8
    Thanks
    1

    Default Re: QTcpSocket/QTcpServer on a heavy load server

    Sorry, I think I made everything kind of confusing. I have tried using deleteLater.

    I have tried:

    Qt Code:
    1. void TCPInterface::discardClient()
    2. {
    3. QTcpSocket* socket = (QTcpSocket*)sender();
    4. socket->deleteLater();
    5. }
    To copy to clipboard, switch view to plain text mode 

    Which is connected to the signal disconnected. And when doing this I call disconnectFromHost() instead of close() in my last function.

    When using this method, my program will crash. So i am assuming something weird is happening when I delete the socket, but I have no clue as to what it is.

    Also another note. It does not crash every time on delete. I am stress testing my server with a script that is constantly sending me get requests, and It will crash anywhere between the 2nd and 200th packet. When I see a lower amount of traffic going into the server, I have no problem with the server staying up. Any ideas what the cause of this problem could be?

  5. #5
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket/QTcpServer on a heavy load server

    As I understand, you call "deleteLater" then "disconnectFromHost"? You should try to call "disconnectFromHost" and then "deleteLater".
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  6. #6
    Join Date
    Aug 2012
    Posts
    8
    Thanks
    1

    Default Re: QTcpSocket/QTcpServer on a heavy load server

    No, I call disconnectFromHost first. deleteLater is in my slot connected to disconnected signal.

    But that did get me thinking. What if a client disconnected from me while I was doing work(database / response message). I should get a disconnected signal, which will delete the socket(via deleteLater). If I then try and do:

    Qt Code:
    1. if(socket->isWritable() && socket->isOpen())
    To copy to clipboard, switch view to plain text mode 

    socket would be an invalid pointer, and then crash my program. Is there anyway to protect myself from this?


    Added after 22 minutes:


    Well, that was defiantly a problem. I set a slot to handle the destroyed() signal of the socket, and set the pointer to NULL there. Then I checked to see if the pointer is NULL before I use it. That did not fix my problem unfortunately, my program will still crash under heavy load.
    Last edited by Eumcoz; 3rd August 2012 at 16:04.

  7. #7
    Join Date
    May 2012
    Posts
    136
    Thanks
    2
    Thanked 27 Times in 24 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QTcpSocket/QTcpServer on a heavy load server

    Try using qobject_cast<QtcpSocket*>(sender()); it will return null if the sender can't be converted (maybe the sender isn't the tcpsocket)

  8. The following user says thank you to StrikeByte for this useful post:

    Eumcoz (6th August 2012)

  9. #8
    Join Date
    Aug 2012
    Posts
    8
    Thanks
    1

    Thumbs up Re: QTcpSocket/QTcpServer on a heavy load server

    Quote Originally Posted by StrikeByte View Post
    Try using qobject_cast<QtcpSocket*>(sender()); it will return null if the sender can't be converted (maybe the sender isn't the tcpsocket)
    That fixed it, not sure why the sender wouldn't have been a tcpsocket, but it worked. Thank you very much!

  10. #9
    Join Date
    Aug 2012
    Posts
    8
    Thanks
    1

    Default Re: QTcpSocket/QTcpServer on a heavy load server

    Actually, I had a typo that prevented the delete. I simplified the problem as much as I think I could. My new train of thought is that my server crash has something to do with the Event Loop.

    I have attached a simple program that replicates the problem, however you need to have a client that will disconnect from the server before the response comes back or I don't think the problem will happen. If you don't want to download the program here's the guts of the program.

    Qt Code:
    1. TCPInterface::TCPInterface(QObject *parent) : QTcpServer(parent)
    2. {
    3. listen(QHostAddress::Any,80);
    4. connect(this, SIGNAL(toDB(QTcpSocket*)), App::getInstance()->getDatabase(), SLOT(fromInterface(QTcpSocket*)), Qt::QueuedConnection);
    5. connect(App::getInstance()->getDatabase(), SIGNAL(sendToInterface(QTcpSocket*)), this, SLOT(fromDB(QTcpSocket*)), Qt::QueuedConnection);
    6. }
    7.  
    8. void TCPInterface::incomingConnection(int socket)
    9. {
    10. QTcpSocket *s = new QTcpSocket(this);
    11. connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
    12. connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
    13. s->setSocketDescriptor(socket);
    14. }
    15.  
    16. void TCPInterface::readClient()
    17. {
    18. QTcpSocket* socket = (QTcpSocket*)sender();
    19.  
    20. emit toDB(socket);
    21. }
    22.  
    23. void TCPInterface::discardClient()
    24. {
    25. QTcpSocket* socket = (QTcpSocket*)sender();
    26. socket->deleteLater();
    27. }
    28.  
    29. void TCPInterface::fromDB(QTcpSocket *socket)
    30. {
    31. QString tmp = "HTTP/1.0 200 Ok\r\n";
    32. tmp += "Content-Type: text/html; charset=\"utf-8\"\r\n";
    33. tmp += "\r\nTest\n";
    34.  
    35.  
    36. socket->write(tmp.toAscii());
    37. socket->disconnectFromHost();
    38. }
    To copy to clipboard, switch view to plain text mode 

    and

    Qt Code:
    1. void DatabaseInterface::fromInterface(QTcpSocket *socket)
    2. {
    3. emit sendToInterface(socket);
    4. }
    To copy to clipboard, switch view to plain text mode 

    Some things I have noted
    1) The script I am using to test my server will often disconnect before a response is sent.
    2) The server will not crash unless the socket is passed to a different thread.
    3) From the backtrace it seems like the crash has something to do with the event loop.

    I am assuming that since my QTcpSocket my server is crashing on the client disconnecting because the of the different event loops, but not sure of the exact reason. Has anyone had this problem before? Is there a better way I should be designing my server to avoid this problem?

    Here is the backtrace that I got when my server crashed.

    Error: signal 11:
    ./SimpleTCPServer[0x401ce6]
    /lib64/libc.so.6[0x3c14032920]
    /home/root/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtCore.so.4(_ZN9QIODevice5writeEPKcx+0x22)[0x7fac6b5a6d22]
    ./SimpleTCPServer[0x401fb6]
    /home/root/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtCore.so.4(_ZN7QObject5eventEP6QEvent+0x38e)[0x7fac6b62cbae]
    /home/root/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtCore.so.4(_ZN16QCoreApplication14notifyIntern alEP7QObjectP6QEvent+0x8c)[0x7fac6b61a30c]
    /home/root/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtCore.so.4(_ZN23QCoreApplicationPrivate16sendP ostedEventsEP7QObjectiP11QThreadData+0x3d3)[0x7fac6b61ebf3]
    /home/root/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtCore.so.4(+0x1c7cf3)[0x7fac6b64bcf3]
    /lib64/libglib-2.0.so.0(g_main_context_dispatch+0x22e)[0x3c15438f0e]
    /lib64/libglib-2.0.so.0[0x3c1543c938]
    /lib64/libglib-2.0.so.0(g_main_context_iteration+0x7a)[0x3c1543ca3a]
    /home/root/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtCore.so.4(_ZN20QEventDispatcherGlib13processE ventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE+0 x73)[0x7fac6b64b833]
    /home/root/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtCore.so.4(_ZN10QEventLoop13processEventsE6QFl agsINS_17ProcessEventsFlagEE+0x32)[0x7fac6b618ec2]
    /home/root/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtCore.so.4(_ZN10QEventLoop4execE6QFlagsINS_17P rocessEventsFlagEE+0x164)[0x7fac6b619334]
    /home/root/QtSDK/Desktop/Qt/4.8.1/gcc/lib/libQtCore.so.4(_ZN16QCoreApplication4execEv+0xb9)[0x7fac6b61efc9]
    ./SimpleTCPServer[0x401c95]
    /lib64/libc.so.6(__libc_start_main+0xfd)[0x3c1401ecdd]
    ./SimpleTCPServer[0x401b59]
    Attached Files Attached Files

  11. #10
    Join Date
    Aug 2008
    Location
    Ukraine, Krivoy Rog
    Posts
    1,963
    Thanked 370 Times in 336 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTcpSocket/QTcpServer on a heavy load server

    Can you also add your script to test the app?
    Qt Assistant -- rocks!
    please, use tags [CODE] & [/CODE].

  12. #11
    Join Date
    Aug 2012
    Posts
    8
    Thanks
    1

    Default Re: QTcpSocket/QTcpServer on a heavy load server

    Sure I am using a simple php script:

    Qt Code:
    1. <?php
    2. //$host = '10.1.10.36';
    3. $host = '10.1.10.43';
    4.  
    5. $port = 80;
    6.  
    7. $service_uri = '/7';
    8.  
    9. while (true) {
    10. $fp = fsockopen($host, $port) or die ("Could not open a connection to host <i>$host</i> on port <i>$port</i>.");
    11.  
    12. # compose HTTP request header
    13. $header = "Watch Your Mouth";
    14. fputs($fp, "GET $service_uri HTTP/1.1\r\n");
    15. fputs($fp, "GET \r\n");
    16.  
    17. fputs($fp, $header);
    18.  
    19. }
    20.  
    21.  
    22. ?>
    To copy to clipboard, switch view to plain text mode 

    Attached is also a slightly better version of the server that makes sure that a socket is valid(has not been destroyed), before using the socket.

    And also, the server does not crash right away, the more traffic going threw it, the more of a chance it will crash.
    Attached Files Attached Files

Similar Threads

  1. My server (using QTcpServer and QTcpSocket) crashes
    By supergillis in forum Qt Programming
    Replies: 3
    Last Post: 2nd June 2010, 15:32
  2. QTcpServer - get the correct QTcpSocket
    By elcuco in forum Qt Programming
    Replies: 4
    Last Post: 11th May 2010, 09:49
  3. QTcpServer QTcpSocket problem
    By jmsbc in forum Qt Programming
    Replies: 0
    Last Post: 20th November 2009, 17:42
  4. QTcpSocket, QTcpServer problem
    By frido in forum Qt Programming
    Replies: 3
    Last Post: 3rd April 2009, 23:16
  5. QTcpServer & QTcpSocket questions...
    By jxmot in forum Qt Programming
    Replies: 2
    Last Post: 24th April 2008, 21:38

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.