2012-08-02 165 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