Socket对传输文件结尾的判定
来源:互联网 发布:淘宝秒刷销量一天千单 编辑:程序博客网 时间:2024/04/30 16:10
再调用socket API进行传输时会涉及到很多细节的问题,其中一条便是文件传输的结尾判定。
这里的文件指广泛的文件而不单字符文件,因此无法使用EOF或者‘\0’来判定文件什么时候结束。
如果不进行恰当的判定,接收方将重复接收最后一个buf里面的内容。直至填满整个文件!
很多人提到了传输文件之前先发送文件长度。这样通过对比该长度与接收到的长度来判定是否继续写入文件。
这是一个比较麻烦,但是很好的机制,特别是对于二进制流传输的文件。
我一开始客户端添加进这一行:
#define MAX 1024unsigned char buf[MAX];while((fileBytes = recv(sockfd, buf, sizeof(buf), 0)) && (locallen < filelen)) {//filelen是服务器发送过来的文件长度if(fileBytes == -1) {perror("fail to receive datas\n");exit(1);}fwrite(buf, sizeof(char), MAX, infp);locallen += fileBytes;//已接收文件长度}
可是马上我就发现这段代码并不奏效。或者说不那么奏效,虽然接收到的文件不再肆意膨胀,但是与源文件长度依然有距离。
最终结果表现为以下两点:
1/传输小于1024Bytes的文件时,以545Bytes文本文件为例,会将文件自动用\0补齐至1024Bytes整。
2/传输大文件时,以JPG图片为例,图片上半部分正常,下半部分色块乱码。
可以判断问题依然出在文件结尾部分。分析如下:
情况1,服务器端进行了正确的传送,但是在写入时误将写入长度设为1024Bytes,因此前545bytes正确写入,后面补入不可预知字符。
情况2,由于文件长度很难是1024的整数倍大小,因此当传输到最后部分时剩余大小将小于1024,此时进入情况1
我还不得不说情况3,当你发现文件本身是8.5M而接收到11.7M时,或许会疑惑,按上面分析最多也就多1024Bytes阿,怎么会多出好几M?!事情是这样的,再传输过程中,由于网络环境的不稳定,不是每次都能保证传输1024Bytes,因此中间可能也在未收到1024的情况下写入了1024。
下面给出解决代码:
while((fileBytes = recv(sockfd, buf, sizeof(buf), 0)) && (locallen < filelen)) {if(fileBytes == -1) {perror("fail to receive datas\n");exit(1);}diff = filelen - locallen;if(diff < 0) //应付情况1fwrite(buf, sizeof(char), filelen, infp);else if(diff < MAX) { //应付情况2/3fwrite(buf, sizeof(char), diff, infp);locallen += diff;}else { fwrite(buf, sizeof(char), fileBytes, infp);}locallen += fileBytes;}}
- Socket对传输文件结尾的判定
- 基于Java的socket对文件的传输
- 使用Socket实现文件的传输
- 简单的用socket传输文件程序。
- socket的UDP传输文件java源代码
- Socket局域网多线程传输文件的方法
- Socket编程实现文件的传输
- socket传输小文件的一个思考
- 基于TCP的Socket文件双向传输
- 文件结尾的判断
- Socket传输文件示例
- Socket传输文件
- Socket传输文件_new
- 简单socket传输文件
- Socket传输文件示例
- java Socket传输文件
- socket传输文件
- SOCKET传输数据、文件
- 利用HtmlClient生成静态页面
- linux常用命令学习之awk命令
- 【学习笔记】事件如何使用
- androidlayout_weight讲解
- 网易笔试题目
- Socket对传输文件结尾的判定
- Re-installation failed due to differentapplication signatures.
- Android应用程序的代码混淆和签名
- 蓄水池算法
- 第四周实验报告1(计算三角形的周长面积)
- Java 程序员应该了解的 10 个面向对象设计原则
- js select 下拉菜单
- Eclipse调试常用技巧
- Linux(VPS+Debian)搭建配置VPN(PPTP)服务