我的c ++客户端/服务器文件交换实现很慢......为什么?

Ben*_*n J 1 c++ sockets

您已经通过c ++中的客户端/服务器连接实现了简单的文件交换.工作得很好,除了一个很慢的问题.这是我的代码:

用于发送文件:

int send_file(int fd)
{

char rec[10];
struct stat stat_buf;
fstat (fd, &stat_buf);  
int size=stat_buf.st_size;

while(size > 0)
{
    char buffer[1024];
    bzero(buffer,1024);
    bzero(rec,10);
    int n;
    if(size>=1024)
    {
        n=read(fd, buffer, 1024);

        // Send a chunk of data
        n=send(sockFile_, buffer, n, 0 );

        // Wait for an acknowledgement
        n = recv(sockFile_, rec, 10, 0 );
    }
    else // reamining file bytes
    {
        n=read(fd, buffer, size);
        buffer[size]='\0';
        send(sockFile_,buffer, n, 0 );
        n=recv(sockFile_, rec, 10, 0 ); // ack
    }

    size -= 1024;

}

// Send a completion string
int n = send(sockFile_, "COMP",strlen("COMP"), 0 );
char buf[10];
bzero(buf,10);
// Receive an acknowledgemnt
n = recv(sockFile_, buf, 10, 0 );

return(0);
}
Run Code Online (Sandbox Code Playgroud)

并接收文件:

int receive_file(int size, const char* saveName)
{

ofstream outFile(saveName,ios::out|ios::binary|ios::app);


while(size > 0)
{       
    // buffer for storing incoming data
    char buf[1024];
    bzero(buf,1024);
    if(size>=1024)
    {

        // receive chunk of data
        n=recv(sockFile_, buf, 1024, 0 );

        // write chunk of data to disk
        outFile.write(buf,n);

        // send acknowledgement
        n = send(sockFile_, "OK", strlen("OK"), 0 );

    }
    else
    {
        n=recv(sockFile_, buf, size, 0 );
        buf[size]='\0';
        outFile.write(buf,n);
        n = send(sockFile_, "OK", strlen("OK"), 0 );
    }   

    size -= 1024;

}

outFile.close();

// Receive 'COMP' and send acknowledgement
// ---------------------------------------
char buf[10];
bzero(buf,10);
n = recv(sockFile_, buf, 10, 0 );
n = send(sockFile_,  "OK", strlen("OK"), 0 );
std::cout<<"File received..."<<std::endl;

return(0);
}
Run Code Online (Sandbox Code Playgroud)

现在这是我最初的想法:也许缓冲区太小了.因此,我应该尝试从I dunno,1024字节(1KB)到65536(64KB)块增加大小.但这会导致文件损坏.好的,所以在每个1024字节的数据块发送完毕后,由于需要接收确认,代码也可能会变慢,所以为什么不删除它们呢?不幸的是,这导致块没有以正确的顺序到达,因此文件损坏.

也许我可以事先将文件拆分成块并创建多个连接并通过自己的线程连接发送每个块,然后以某种方式在接收器中重新组装块....

知道如何让文件传输过程更高效(更快)吗?

谢谢,本.

Fru*_*nsi 11

跳过缓冲区的确认!您可能为每个数据包插入一个人工往返(服务器 - >客户端+客户端 - >服务器).

这会减慢转移速度.

你不需要这个ack.您正在使用TCP,它为您提供可靠的流.发送字节数,然后发送整个文件.这样做readsend等.

编辑:作为第二步,您应该增加缓冲区大小.对于互联网传输,您可以假设MTU为1500,因此每个IP数据包中有1452字节的有效负载空间.这应该是您的最小缓冲区大小.使其更大,让操作系统将缓冲区切成数据包.对于LAN,您有更高的MTU.


Ric*_*ton 6

我的猜测是你不同步,你的一些读数小于1024.它一直发生在套接字上."size - = 1024"语句应为"size - = n".

我的猜测是,从recv()开始,n有时小于1024.


小智 5

您当然应该增加缓冲区大小,如果这会导致损坏,那么您需要修复代码中的错误.此外,如果您使用流协议(即TCP/IP),则可以保证数据包的顺序和传送.