c - 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 左右的大文件,视频或可执行文件会损坏。我不知道为什么会发生这种情况,任何帮助将不胜感激。
解决方案
您的代码中的主要问题是您假设send()
并且recv()
始终成功并发送和/或接收请求的字节总数。这是不正确的:您必须检查这些函数的返回值并采取相应措施。
还有其他问题,但是您没有发布可编译的程序,因此缺少大量代码以进行更完整的分析。
推荐阅读
- postgresql - PostgreSQL 错误代码,设置自定义错误代码
- javascript - 在 Angular 5 的帮助下渲染页面时出错
- html - 如何从 html 调用谷歌脚本函数
- c# - c# 字符串常量与静态属性
- javascript - 如何在 JS 函数中动态设置键值?
- sql-server - SQL Server UDF函数替换列中的字符
- javascript - 嵌套数组 - 如何将一行元素添加到嵌套 JavaScript 数组
- mysql - 错误代码:1267。排序规则(latin1_swedish_ci,IMPLICIT)和(utf8_general_ci,COERCIBLE)的非法混合
- typescript - Typescript - 为什么不能推断出这个字符串文字类型?
- go - 在golang中处理逻辑错误与编程错误的惯用方法