-
产生的原因:TCP通信中数据包是连续、首尾相连的、没有边界的流形式,连续发送多个不同的文件时,接收端无法识别分开发送过来的多个数据。
-
解决方案:
- 时间边界:延时发送。
- 空间边界:填空数据。
- 额外标志:如结束字符(a. 接收要额外解析识别; b. 内容不能再出现这个标记字符)。
- 自定义协议头:协议头传递重要的信息,如文件名、文件大小。
在使用第四种方法时,客户端根据协议头中的文件大小接收文件,一开始我使用这样的while循环接收文件。
size = head.length; //文件大小
while (size > 0)
{
cnt = read(client_fd, r_buffer, RECVSIZE); //接收文件内容
write(file_fd, r_buffer, cnt);
size -= cnt;
}
出现了第二个文件无法正常接收的问题,经过一番排查,发现原因如下:
- 根据文件大小接收文件时,如果判断条件是while(size>0),由于每次接收的大小n是固定RECVSIZE的,且后面跟着下一个文件的数据,这样会导致最后一次把下一个文件的数据(协议头)也接收了,经过size-=cnt后size小于0。这样虽然能使循环终止,但由于拿到了下一个文件的内容,导致接收的第一个和第二个文件都发生错误。
修改循环条件:
// int cnt1 = 0;
size = head.length;
while (size > sizeof(r_buffer))
{
cnt = read(client_fd, r_buffer, RECVSIZE); //接收文件内容
write(file_fd, r_buffer, cnt);
size -= cnt;
// cnt1 += cnt;
}
cnt = read(client_fd, r_buffer, size); //size此时不为0
// cnt1 += cnt;
// printf("DEBUG recvlen: %d\n", cnt1);
接收正常,问题解决!