TCP接收端如何判断文件接收结束

wangying_great 2017-09-07 05:14:58
我要写一个文件服务器和文件客户端。文件服务器先read本地文件,然后send文件,如此循环发送。等到read的返回值为0,则表示文件发送结束,跳出循环。文件客户端通过while(recv(sockfd, recvbuf, sizeof(recvbuf), 0) > 0)循环来接收服务器发送过来的文件,但是问题来了,当服务器发送完毕跳出循环,但是客户端并不知道,当接收缓冲区没有内容时,一直阻塞在while这里,无法跳出。想请教各位大神,服务器怎样告知客户端文件已经发送结束?
说明:我也上网查过,好像有一些人说,包头带上长度,或者最后的一次发送一个文件结束符,但我不是很明白。不知道有没有大神能给出大致的代码呢
...全文
931 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
水目沾 2017-09-08
  • 打赏
  • 举报
回复
引用 9 楼 wangying_great的回复:
[quote=引用 8 楼 mengsofts 的回复:] 因为TCP是以数据流的方式发送数据的,没有边界。所以在发送和接受这里你要进行额外的设计,可以在第一次通信的时候把文件的长度传给客户端,在在客户端收到这么长数据的时候退出即可。
对对对,昨天看了一晚上,终于知道发送端这边的基本思路了。就是在发送文件内容之前,定义一个结构体,将文件数据,以及文件数据的长度,还有一些你自己想要的一些信息放在结构体中,一并发送给客户端。[/quote] 聪明,结构体至少应该包括文件名、文件大小和文件md5(用来检验)。
水目沾 2017-09-08
  • 打赏
  • 举报
回复
聪明,结构体至少应该包括文件名、文件大小和文件md5(用来检验)。
wangying_great 2017-09-08
  • 打赏
  • 举报
回复
引用 8 楼 mengsofts 的回复:
因为TCP是以数据流的方式发送数据的,没有边界。所以在发送和接受这里你要进行额外的设计,可以在第一次通信的时候把文件的长度传给客户端,在在客户端收到这么长数据的时候退出即可。
对对对,昨天看了一晚上,终于知道发送端这边的基本思路了。就是在发送文件内容之前,定义一个结构体,将文件数据,以及文件数据的长度,还有一些你自己想要的一些信息放在结构体中,一并发送给客户端。
水目沾 2017-09-08
  • 打赏
  • 举报
回复
因为TCP是以数据流的方式发送数据的,没有边界。所以在发送和接受这里你要进行额外的设计,可以在第一次通信的时候把文件的长度传给客户端,在在客户端收到这么长数据的时候退出即可。
wangying_great 2017-09-07
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
谢谢啦,虽然看的一知半解。哈哈
赵4老师 2017-09-07
  • 打赏
  • 举报
回复 1
不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊! http://bbs.csdn.net/topics/380167545
wangying_great 2017-09-07
  • 打赏
  • 举报
回复
引用 4 楼 adlay 的回复:
客户端再请求文件可以再 connect 重新建立一条链接来呀 把传控制协议的通道和传数据的通道分开是最好的.
其实我也是这么做的,建立两条通道,一个请求文件,一个接收文件。但是整个大程序是在一个epoll的监听集合里(不是使用fork创建子进程的方式),如果两条连接的话,就必须给这两条连接建立关联,而且连接变多的话,整个epoll程序会变复杂很多。所以我觉得可能只用一条连接,不用通过断开连接就能结束接收的话程序会变简单很多。
www_adintr_com 2017-09-07
  • 打赏
  • 举报
回复
客户端再请求文件可以再 connect 重新建立一条链接来呀 把传控制协议的通道和传数据的通道分开是最好的.
wangying_great 2017-09-07
  • 打赏
  • 举报
回复
这条连接不能关闭,因为在这个文件发送结束后,客户端可能还要继续请求文件,如果这条连接关闭了,客户端就不能继续请求文件了。
自信男孩 2017-09-07
  • 打赏
  • 举报
回复
一种办法是服务器发送结束就直接断开连接,但是如果还有其他业务需要通信这种办法不太靠谱; 另一种办法是,服务器先给客户端发送文件的大小,然后客户端通过这个大小自己决定何时结束;
www_adintr_com 2017-09-07
  • 打赏
  • 举报
回复
发送文件的一端发送完成后把 socket close 掉接收端的 recv 就会返回 0 了

69,372

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧