2012-08-02 44 views
1

我正在設計和製作一個服務器,應該能夠處理大約每秒100次點擊。我從服務器獲取的信息只是HTTP頭。根據頭信息,它將查詢一個數據庫(不同的線程)的一些信息,並將最終的信息發送回QTcpServer,它創建一個輸出字符串,併發回一個HTTP響應。我遇到了一個很大的問題,我無法調試。我的代碼類似於此:QTcpSocket/QTcpServer內存管理/服務器崩潰

TCPInterface::TCPInterface(QObject *parent): QTcpServer(parent) 
{ 
    //start listening for tcp traffic on port 80 
    listen(QHostAddress::Any, 80); 

    connect(this,SIGNAL(sendInfo(QTcpSocket*, QString *)), databaseThread, SLOT(recieveInfo(QTcpSocket*, QString*))); 
    connect(databaseThread, SIGNAL(sendToTCPSend(QTcpSocket *, QString *)), this, SLOT(TCPSend(QTcpSocket*, QString*))); 
} 

`

void TCPInterface::incomingConnection(int socket) 
{ 
    QTcpSocket *s = new QTcpSocket(this); 
    connect(s, SIGNAL(readyRead()), this, SLOT(readClient())); 
    //connect(s, SIGNAL(disconnected()), this, SLOT(discardClient())); 

    s->setSocketDescriptor(socket); 
} 

`

//void TCPInterface::discardClient() 
//{ 
    //QTcpSocket* socket = (QTcpSocket*)sender(); 
    //socket->deleteLater(); 
//} 

`

void TCPInterface::readClient() 
{ 
    QTcpSocket* socket = (QTcpSocket*)sender(); 

    QString header; 
    while(socket->canReadLine()) 
    { 
     header += socket->readLine(); 
    } 

    emit sendInfo(socket, headerInfo); 
} 

`

void databaseThread::recieveInfo(QTcpSocket* socket, QString* headerInfo) 
{ 
    QString*outputInfo = getDatabaseInfo(headerInfo); 
    emit sendToTCPSend(socket, outputInfo); 
} 

`

void TCPInterface::TCPSend(QTcpSocket* socket, QString* outputInfo); 
{ 
    QString response = "HTTP/1.0 200 Ok\r\n"; 
    response += "Content-Type: text/html; charset=\"utf-8\"\r\n"; 
    response += "\r\n" + *outputInfo + "\n"; 

    if(socket->isWritable() && socket->isOpen()) 
    { 
     socket->write(response.toAscii()); 
    } 
    //socket->disconnectFromHost(); 
    socket->close(); 
    delete headerInfo; 
} 

我具有我有一個想法是什麼一個主要問題,但無法找到一個解決方案來解決這個問題。

我的問題是我的記憶力不斷增加,因爲我得到更多的命中。我確信這是我的QTcpSockets永遠不會被刪除,因爲我只是關閉它們。但是,當我不使用關閉,並使用disconnectFromHost和斷開連接/ discardClient插槽/信號我的服務器將崩潰與交通繁忙(沒有消息或任何東西,所以我不知道崩潰的確切原因)。有沒有人遇到過這個問題?任何想法。

回答

0

你應該叫deleteLater()客戶端套接字:

connect(socket, SIGNAL(disconnected()), 
     socket, SLOT(deleteLater())); 
0

對不起,我想我做的一切形式的混亂。我曾嘗試使用deleteLater。

我有:被連接到斷開信號

void TCPInterface::discardClient() 
{ 
    QTcpSocket* socket = (QTcpSocket*)sender(); 
    socket->deleteLater(); 
} 

該函數導致我的程序崩潰。無論如何,deleteLater會導致崩潰。我不這麼認爲,但我想不出任何其他原因,當我刪除我的套接字時,我的程序會崩潰。

另一個說明。它不會在每次刪除時崩潰。我正在用一個不斷髮送請求的腳本測試我的服務器,並且它會在第2個和第200個數據包之間的任何地方崩潰。

+0

嘗試創建一個最小的工作示例,在重負載時產生崩潰。如果這是由Qt事件系統中的競爭條件引起的,我不會太驚訝。 – scai 2012-08-03 04:36:29

1

我有同樣的問題!

close()假定爲對象的構造函數。 (QT手冊QTcpSocket ::〜QTcpSocket()) 那裏我建議做一個實驗:關閉一個套接字,並嘗試重新打開它。如果它失敗,這意味着套接字對象被銷燬,如果不意味着該對象應該是deletelater()..

在我的情況下連接被客戶端關閉,並在那裏調用disconnect()SIGNAL並且它觸發相應的方法到您的discardClient()SLOT,其中我deletelater()套接字。 當我對它進行壓力測試時,它通常會在I5筆記本電腦雙核上同時以600-800連接轟擊時崩潰。它平均每5次崩潰。

其他方面它不。

樂於進一步討論。

Gil