【发布时间】:2020-11-25 17:47:04
【问题描述】:
我正在编写一个程序,客户端尝试从服务器下载文件。
以下是客户端的代码。
FILE * file_to_download;
file_to_download = fopen("CLIENT_file_downloaded", "ab");
long int total_bytes = 0;
int bytes_received = 0;
char received_buffer[2048];
printf(">>> Downloading file...\n");
while ((bytes_received = read(connector, received_buffer, sizeof received_buffer)) > 0) { // keep receiving until data stops sending
printf("=");
total_bytes += bytes_received;
fwrite(received_buffer, 1, bytes_received, file_to_download);
}
if (bytes_received < 0) {
printf("\n>>> Read error\n");
exit(1);
}
printf("\n>>> File downloaded (Bytes received: %ld)\n\n", total_bytes);
当我立即关闭套接字连接时,这非常有效,但是,如果我将它打开以执行其他一些功能(比如向服务器发送消息),它会在“>>>下载文件.. .”,但是,我可以在文件夹中看到下载的文件。此外,一旦我终止服务器端程序,它会打印出其他所有内容。
从其他 SO 线程来看,我认为这与套接字“阻塞”有关。
- 但是为什么我的文件被下载了(我可以在文件夹中看到它)?
fwrite函数负责这个在 while 循环内,但如果它在 while 循环内,为什么它不打印任何东西? - 如何让服务器告诉客户端它已完成向其发送数据以及如何让客户端程序继续前进?
【问题讨论】:
-
我认为缓冲区不知道何时停止等待,您最好询问文件大小,然后准确读取我认为的那么多字节
-
@WARhead 就是这样。 OP 拥有的唯一协议是连接打开/关闭,因此,如果没有它,recv() 调用将永远不会返回 0,while 循环将永远不会退出:(
-
WARhead 建议先发送文件的长度,这可能是解决问题的最简单方法。确保以具有已知字节序的固定宽度整数发送长度,因为如果您只使用
int,您永远不知道接收器是否有 16 位、32 位、64 位或任何大小的int或哪个字节订单正在使用中。 -
首先发送文件大小就是这样一种协议,但请记住,这并不像乍看起来那么简单。你的整个 TCP 系统应该被设计/编写,即使每个读取数据的 recv() 调用只读取一个字节并返回 1,它仍然可以正常工作。
-
@Shreya 您应该研究现有的文件传输协议,如 FTP 和 HTTP。然后,如果您选择不使用现有协议,我强烈建议您记录您将要实现的协议,即使它只有几段。
标签: c network-programming