首页 > 解决方案 > C套接字下载功能传输损坏的文件

问题描述

我正在尝试在 C 套接字中实现下载。这个想法是在客户端获取文件的大小并一次发送 1024 个字节,多次发送,然后发送剩余的字节。在服务器端,您将收到这些字节,并将它们附加到运行时创建的文件中。

这是客户端代码。

char localfilename[260];
if (get_string_between_spaces(localfilename, buffer, sizeof(buffer), 1, 2) == -1)   {
    /*
    the function above goes through the buffer where a command is stored , like "download hi.txt hello.txt and stores into localfilename "hi.txt"
    */
    send_message(sock, "error", sizeof("error")); //this function is a wrapper for send()
    goto jump;
}
FILE *pLOCALFILE;
pLOCALFILE = fopen(localfilename, "rb");
if (!pLOCALFILE) {
    send_message(sock, "File not found on target system.Exiting..\n", sizeof("File not found on target system.Exiting..\n"));
    goto jump;
} else {
    send_message(sock, "File found target system going on...\n", sizeof("File found target system going on...\n"));
}
int size_of_file = get_file_size(pLOCALFILE); //returns the size of the file
int remainder = size_of_file % 1024; 
int quotient = size_of_file / 1024;

send_integer(sock, size_of_file);
send_integer(sock, remainder);
send_integer(sock, quotient);
for (int i = 0; i < quotient; i++) {
    /*
     you will want to send 1024 bytes for quotient times 
    */
    fread(container, 1, 1024, pLOCALFILE);
    send(sock, container, sizeof(container) , 0);
    memset(container, 0, sizeof(container));
}
//send over the remaining bytes
//if quotient == 0 the for loop doesn't get executed , the file transfer being done in one send() instruction
fread(container, 1, remainder, pLOCALFILE);
send(sock, container, remainder, 0);
memset(container, 0, sizeof(container));
fclose(pLOCALFILE);

这是服务器代码。

char filename[260];
get_string_between_spaces(filename, buffer, sizeof(buffer), 2, 3);
/*
    the function above goes through the buffer 
where a command is stored , like "download hi.txt 
hello.txt and stores into localfilename "hello.txt"
*/
FILE *pFILETOWRITE;
pFILETOWRITE = fopen(filename, "ab");//open the file in append bytes mode
if (pFILETOWRITE) {
    printf("The file %s has been opened.\n", filename);
} else {
    printf("Couldn't open the %s file.\n", filename);
    goto jump;
}
            
recv(client_socket, receive_response, sizeof(receive_response), 0);
printf("%s\n", receive_response);
//the receive response above receives the ok to continue if we were able to open the file on the client
char containerOFmode[1024];
bzero(containerOFmode, sizeof(containerOFmode));
int size_of_client_file = recv_integer(client_socket);
int remainder = recv_integer(client_socket);
int quotient= recv_integer(client_socket);
int bytes_transferred = 0;
printf("%d bytes are to be transferred.\n", size_of_client_file);
printf("The remainder is %d\n", remainder);
printf("The cat is %d\n", quotient);
//receive and print the size of the file , the quotient and the remainder           
for (int i = 0; i < quotient; i++) {
    recv(client_socket, containerOFmode, sizeof(containerOFmode), 0);
    bytes_transferred += sizeof(containerOFmode);
    fwrite(containerOFmode, sizeof(char), sizeof(containerOFmode), pFILETOWRITE);
    printf("%s\n", containerOFmode);
    printf("The size of this send was:%d\n", sizeof(containerOFmode));
    printf("Bytes transferred so far:%d\n", bytes_transferred);
    bzero(containerOFmode, sizeof(containerOFmode));
    /*
        for each iteration receive the 1024 bytes and write it to the pFILETOWRITE , while also being verbose to the console
    */
}
recv(client_socket, containerOFmode, remainder. 0);
bytes_transferred += remainder;
fwrite(containerOFmode, sizeof(char), remainder, pFILETOWRITE);
printf("%s\n", containerOFmode);
printf("The size of this send was:%d\n", remainder);
printf("Bytes transferred so far:%d\n", bytes_transferred);
bzero(containerOFmode, sizeof(containerOFmode));
/*
        receive the remaining bytes and write it to the pFILETOWRITE , while also being verbose to the console
*/
fclose(pFILETOWRITE);
goto jump;//                                                                                                 

问题是对于超过 10 MB 左右的大文件,视频或可执行文件会损坏。我不知道为什么会发生这种情况,任何帮助将不胜感激。

标签: csocketsdownload

解决方案


您的代码中的主要问题是您假设send()并且recv()始终成功并发送和/或接收请求的字节总数。这是不正确的:您必须检查这些函数的返回值并采取相应措施。

还有其他问题,但是您没有发布可编译的程序,因此缺少大量代码以进行更完整的分析。


推荐阅读