vc++-Ftp客户端代码-上传文件非常慢

vc++-Ftp客户端代码-上传文件非常慢,c++,winapi,visual-c++,ftp,logic,C++,Winapi,Visual C++,Ftp,Logic,我正在写一个ftp客户端来上传文件。伪代码如下所示 { command_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); login...// pass.. // passive mode get the address from the reply ... // data_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); connec

我正在写一个ftp客户端来上传文件。伪代码如下所示

{

    command_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    login...//

    pass.. // passive mode

    get the address from the reply ... // 

    data_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    connect the data_Socket to that address ..//

    open the file using createFile(....) //

    loop
    {
        char buf[1000];

        readFile and fill the buf //

        send(dataSocket,buf,..);
    }

}
现在,问题是上传速度是20 kB/s,即使我在同一台机器上上传文件。但是当一个人使用ftp上传一个文件时,他的机器是ubuntu,上传速度是10MB/s。我无法理解这背后的逻辑

注意:我使用的是FileZilla FTP服务器,它能够显示客户端文件的上传/到达速度

我建议使用内存映射I/O 如果要使用ReadFile API函数,请不要按1000字节读取

2.1读取2^k字节1024、2048、4096等

2.2对于大文件,每次迭代读取的字节数超过1024字节—太小。尝试将其增加到4MB或类似的大小。根据文件大小的不同,可以执行此操作

2.3您可以使用异步I/O从文件中读取下一个区块,而上一个区块通过发送发送


嗯。。。其他人可能会提出更多建议。

发布伪代码可能隐藏了重要的性能问题。所以不清楚如何填充变量buf


但是您不应该发送1000字节的块。这可能会导致TCP在服务器端发送ACK的频率超过必要的频率。

您的伪代码遗漏了一些重要的细节,但我将进行一些猜测来弥补:-

尝试使套接字非阻塞,使用select知道何时可以写入,并写入略低于64K的块 当套接字正在异步发送时,现在可以读取文件的下一个块 您的伪代码现在变成:

{
   command_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    login...//
    pass.. // passive mode
    get the address from the reply ... // 
    data_Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    /* set data socket to non-blocking  */
    connect the data_Socket to that address ..//
    open the file using createFile(....) //
    /* read a chunk */
    loop
    {
        select
        send data
        readFile and fill the buf //
    }
}

使套接字非阻塞允许您的代码在套接字执行时立即返回。知道该做什么,所以您不必在它做您需要它做的事情时等待—这意味着您可以在发送数据时读取文件。

您是否认为ReadFile正在减慢过程?。至于我所关心的,系统调用是最快的函数调用。实际上不是ReadFile,而是您使用它的方式:不要读取666或1231字节。真的很慢。读取2^k字节。对于大文件来说,按大小为1024字节的块读取1GB需要1048576次迭代。您可能应该增加缓冲区的大小。现在我将套接字置于非阻塞模式,但速度仍然很慢。但就我所知,阻塞/非阻塞不能被视为异步I/o。非阻塞意味着套接字发现没有进一步的发送/接收,然后完成发送/接收。对于写入非阻塞套接字,数据被复制到套接字的缓冲区中,并从那里异步处理。对于从非阻塞套接字读取,您是对的:这意味着如果没有可读取的内容,它将简单地返回,即生成一个WILL block错误。我建议的想法是确保您的套接字实现。总是有数据要发送。如果仅仅使套接字非阻塞没有帮助,你能告诉我你的客户端代码在哪里花费时间吗?例如,测量它在循环的每个部分花费的时间。你可以尝试的另一件事是通过将TCP_节点延迟设置为套接字选项来取消激活Nagle的算法。如果这有帮助,它基本上意味着你的块大小仍然太小,所以你应该增加它。当你完成实验后,纳格尔真的应该回来了。。