文件传输
文件传输
1.创建客户端,服务器端代码结构
将服务器端拆分为几个代码,以至于实现起来较方便些,
C/S(客户端/服务器端)
(服务器端与客户端链接上后)客户端做的事:
1.查看服务端文件列表
改文件名,删除,新建文件
2.下载,显示百分百
断点下载
3.上传(通过客户端向服务器端上传文件)
秒传
传输层选择tcp协议,
应用层:制定协议(私有)
设备:c/c++
linux项目:(类似百度网盘)
功能:1.查看文件,删除文件,重命名
2.下载,显示百分比
3.上传 校验,秒传
第一步:
首先定协议:eg:01:代表查看文件,02#:代表删除一个文件
c=>s ls (客户端给服务器端发送ls)
s=>c ok#a.txt b.c (服务器端给参数端回复参数列表)(加ok#:防止没有文件的情况,不回复数据,此时recv不会解除阻塞, 此时也会回复一个OK#)
c->s rm a.c (删除文件)
s->c ok# (成功) s->c err (失败)
c->s mv a.c b.c (重命名)
s->c ok# (成功)
c->s get a.c (下载)
c->s up a.c (上传)
第二步:
命令实现:
首先创建一个无名管道,创建一个父进程,然后fork产生子进程,将子进程替换为要执行的命令,替换标准输出和标准错误输出,写在管道中(相当于重定向),父进程将管道终端读出来,然后返回给客户端。
下载:不止交互一次
客户端要让服务器端知道有一个下载的操作(get a.pdf),首先回复一个状态信息(ok(存在)/err(不存在)(则退出)),服务器端给客户端循环发送数据,客户端不断接收,发送端循环当read()==0时,则退出,接收端怎样退出(提前将文件的大小发送过来),中间进行一轮控制,(是否进行传输文件),(要进行防止粘包),(这种设计方式确定一次只能传输一个文件),
让客户端与服务器端重新建立链接,用来发送数据,客户端就可以利用recv为0,判断结束,
(服务器端send(),客户端recv(),)若客户端发生错误,服务器端仍一直发送:会引发信号异常终止
若服务器端发生错误,客户端会结束,造成文件没有接收完
解决方法:当服务器端给客户端发送数据后,客户端给服务器端回复一个数据,代表一次发送完成,(性能降低)
校验:利用md5sum进行处理,无论名字为什么,文件内容不变,(查看文件是否发生变化)
下载文件时,在本地计算一个文件大小,与文件大小进行比较,
秒传:当上传一个文件时,瞬间完成,(本质:没有上传),文件实际上已经存在
下载的时候不可能秒传