【问题标题】:Handling connections from multiple users on a server在服务器上处理来自多个用户的连接
【发布时间】:2014-09-17 12:39:17
【问题描述】:

我正在编写一个程序,我有一个服务器,它需要能够同时处理多个客户端连接,做许多不同的事情。

我正在使用 Qt 库,所以我会像这样处理新连接:

在服务器构造函数中:

Server::Server(QObject* parent): QObject(parent)
{
  connect(&server, SIGNAL(newConnection()), //server is a QTcpServer object
          this, SLOT(acceptConnection())); 
  qDebug() << "[" << currentTime() << "] " << "Server started.";
  server.listen(QHostAddress::Any, PORT_NUMBER);
  qDebug() << "[" << currentTime() << "] " << "Server listening.";
}

acceptConnection 槽:

void Server::acceptConnection()
{
  client = server.nextPendingConnection(); //client is a QTcpSocket* object

  connect(client, SIGNAL(readyRead()), //When there is data to be read
    this, SLOT(startRead()));
}

startRead 槽:

void Server::startRead()
{

    char serverReceiveBuf[65536]; //A buffer for the data sent to the server
    client->read(serverReceiveBuf, client->bytesAvailable());
    handleConnection(serverReceiveBuf); //Do something with that data
}

我不打算给出handleConnection 函数,因为它有点长,而且我认为对于这个问题没有必要。

我担心的是延迟。如果我有一两个用户,那很好。但是我还没有测试过很多并发用户。客户端发送一个同步信号,要求服务器验证客户端拥有的数据与服务器上的数据是否匹配。我每 250 毫秒发送一次此请求,因此如果有更多并发用户,客户端可能会因为其他客户端发送同步请求而每 250 毫秒等待太长时间。

至少,我是这么认为的。 Qt 非常强大,但我不完全确定当收到信号时是否会自动创建一个新线程来处理连接。如果我没记错的话,我处理连接的当前方式涉及排队,这样当服务器接收到信号时,它会按照接收到的顺序处理请求。需要注意的是,在客户端自己终止连接之前,我不会调用client-&gt;close(),因此一旦调用client = server.nextPendingConnecting();client 将一直存在,直到客户端终止他们身边的程序。

鉴于我会定期让用户经常发送同步请求,这是处理多个连接的好方法吗?如果没有,我应该如何处理连接?

【问题讨论】:

  • 启动一个新线程来自动处理新连接会适得其反。您不希望有比 QThread::idealThreadCount 更多的 CPU 绑定线程。

标签: c++ qt sockets networking


【解决方案1】:

我没有测试过很多并发用户。

您怀疑 Qt 可以支持的客户端数量,但如果不对其进行测试,您将不会知道这个限制是多少,尤其是您运行的硬件可以在这里产生很大的不同。

我有几百个同时连接,每个连接都在不断发送和接收数据,没有问题,但我的设置可能与你的不同。

至于您如何设置服务器,我看到您提供的代码只是一个直接的问题。在函数 startRead() 中,您应该知道此时接收到的数据可能不完整。

您需要知道何时收到完整的消息。最简单的方法是在每条消息前面加上消息的大小(以字节为单位),然后在接收到消息的开头时,读取大小并继续将数据附加到缓冲区中,直到获得完整的消息,此时您可以然后调用handleConnection。

【讨论】:

  • 我主要担心服务器的瓶颈是服务器硬件还是因为我编写了错误的代码。对于startRead() 的更改,我使用QByteArray 从客户端发送数据,因此我可以先发送数组的size()。但是,如何让服务器等到它首先收到size() 字节?我知道read() 的第二个参数是要读取的字节数,但是如何确保我只读取传入数据的大小而不读取其余数据?如果我发送一个 int 作为消息大小,我可以只用read(messageSize, 4)吗?
  • 服务器不等待,它退出readyRead并在有更多数据可用时返回。所以你需要将数据缓存在一个成员或静态变量(QByteArray)中,并在收到完整消息时调用handleConnection。
猜你喜欢
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多