C++ 具有大量同步客户端的慢速QTcpServer
我正在用Qt编写TCP服务器,它将服务于大文件。应用逻辑如下:C++ 具有大量同步客户端的慢速QTcpServer,c++,performance,qt,qtcpserver,C++,Performance,Qt,Qtcpserver,我正在用Qt编写TCP服务器,它将服务于大文件。应用逻辑如下: 我已经对qtcserver进行了子分类,并重新实现了incomingConnection(int) 在incomingConnection中,我正在创建“Streamer”类的实例 “拖缆”使用QTcpSocket,该QTcpSocket由incomingConnection中的setSocketDescriptor初始化 当来自客户机的数据到达时,我将从readyRead()插槽中发回初始响应,然后将套接字的信号byteswrit
Streamer.h:
...
private:
QFile *m_file;
char m_readBuffer[64 * 1024];
QTcpSocket *m_socket;
...
Streamer.cpp
...
void Streamer::bytesWritten() {
if (m_socket->bytesToWrite() <= 0) {
const int bytesRead = m_file->read(m_readBuffer, 64 * 1024);
m_socket->write(m_readBuffer, bytesRead);
}
}
...
Streamer.h:
...
私人:
QFile*m_文件;
字符m_readBuffer[64*1024];
QTCP插座*m_插座;
...
拖缆
...
无效拖缆::字节写入(){
if(m_socket->bytesToWrite()读取(m_readBuffer,64*1024);
m_套接字->写入(m_读取缓冲区,字节读取);
}
}
...
所以基本上我只在所有待处理的数据都被完全写入时才写入新数据。我认为这是最异步的方式
所有的工作都是正确的,除了当有很多同时出现的客户机时,速度非常慢
大约有5个客户端-我正在以大约1 MB/s的速度从该服务器下载(我的家庭互联网连接的最大速度)
大约有140个客户端-下载速度约为100-200 KB/s
服务器的互联网连接速度为10 Gbps,140个客户端的使用速度约为100 Mbps,所以我认为这不是问题所在
140个客户端的服务器内存使用率-100 MB 2GB可用
服务器的CPU使用率-最大20%
我正在使用端口800
当端口800上有140个客户端,下载速度大约为100-200kb/s时,我在端口801上运行了单独的拷贝,下载速度为1Mb/s,没有问题
我的猜测是,Qt的事件调度(或套接字通知程序?)太慢,无法处理所有这些事件
我试过:
main.cpp:
#包括
int startWorker(无效*argv){
int argc=1;
QCOREA应用程序(argc,(char**)argv);
工人;
worker.Start();
返回a.exec();
}
在main()中:
...
长栈[16*1024];
克隆(startWorker,(char*)堆栈+sizeof(stack)-64,克隆_文件,(void*)argv);
然后在主进程中启动QLocalServer,并将socketDescriptor从incomingConnection(int socketDescriptor)传递到工作进程。它工作正常,但下载速度仍然很慢
还尝试:
或者我应该使用不同的语言/框架/服务器?我需要提供文件服务的TCP服务器,但我还需要在数据包之间执行一些特定任务,因此我需要自己实现该部分。您的磁盘读取正在阻止操作,它们将停止任何处理,包括处理新的网络连接等。您的磁盘也有有限的I/O吞吐量,您可以使其饱和。您可能不希望磁盘停止应用程序的其余部分。我认为Qt在这里没有任何问题——除非您运行一个分析器,并显示Qt的CPU消耗过多,或者Qt在事件队列上遇到锁争用(这些是这里唯一重要的) 您应该在QoObject之间拆分处理,如下所示:
main.cpp:
#include <sched.h>
int startWorker(void *argv) {
int argc = 1;
QCoreApplication a(argc, (char **)argv);
Worker worker;
worker.Start();
return a.exec();
}
in main():
...
long stack[16 * 1024];
clone(startWorker, (char *)stack + sizeof(stack) - 64, CLONE_FILES, (void *)argv);