实现简单socket的ftp功能
Posted lijunlin-py
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现简单socket的ftp功能相关的知识,希望对你有一定的参考价值。
1、服务器端
1 import socket,os,hashlib 2 server=socket.socket() 3 server.bind(("localhost",9999)) # 绑定套接字 4 5 server.listen() # 服务器监听 6 """ 7 FTP 流程 8 1.读取文件名 9 2.检测文件是否存在 10 3.打开文件 11 4.检测文件大小 12 5.发送文件大小给客户端 13 6.等客户端确认 14 7.开始边读边发数据 15 8.发送md5,双方做对比 16 """ 17 while True: 18 conn,addr=server.accept() # 接收一个套接口的连接 19 20 while True: 21 data=conn.recv(1024) #接收 22 if not data: 23 print("客户端已断开") 24 break 25 cmd,filename= data.decode().split() 26 print(filename) 27 if os.path.isfile(filename): 28 with open(filename,"rb") as f: 29 m=hashlib.md5() # 创建一个md5 30 file_size=os.stat(filename).st_size # 利用os.stat().st_size 获取文件的大小 31 conn.send( str(file_size).encode() ) # send file size 32 client_ack=conn.recv(1024) # wait for ack 防止连续发送导致的粘包 33 for line in f: 34 m.update(line) # 每次接收一行,就更新md5 35 conn.send(line) # send line_data 36 # print("file md5:",m.hexdigest()) 37 conn.send(m.hexdigest().encode()) # send md5_data 38 print("send done...") 39 40 41 server.close()
2、客户端
1 import socket,hashlib 2 3 # 调用进度条功能 4 def progress(percent): 5 if percent>=1: 6 percent=1 7 res=int(percent*50)*"█" 8 print(" [%-50s] %d%%" %(res,int(percent*100)) ,end="") 9 10 # 判断是否下载文件的单位 11 def k_m_g(size): 12 size=int(size) 13 if size<1024**2: 14 return size/1024,"K" 15 elif size<1024**3: 16 return size/(1024**2),"M" 17 else: 18 return size/(1024**3),"G" 19 20 21 client=socket.socket() 22 client.connect(("localhost",9999)) 23 24 done_size=1024 # 设置每次下载长度 25 26 while True: 27 cmd = input(">>:").strip() 28 if len(cmd)==0:continue 29 if cmd.startswith("get"): 30 client.send(cmd.encode(‘utf-8‘)) 31 server_response = client.recv(1024) # 接收文件大小 32 client.send("ready to recv file".encode(‘utf-8‘)) # 响应服务器请求,防止粘包 33 file_total_size = int(server_response.decode()) # 文件的总长度 34 num,msg=k_m_g(file_total_size) 35 print(f‘server response:{round(num,2)}{msg}‘ ) 36 reversed_size=0 37 filename=cmd.split()[1] # 获得get 后的第一个命令 38 with open(filename+‘.new‘,"wb") as f: 39 m=hashlib.md5() 40 recv=0 41 while reversed_size<file_total_size: 42 if file_total_size-reversed_size>done_size: # 判断是否是最后一次传输(防止粘包) 43 size=done_size 44 else: 45 size=file_total_size-reversed_size 46 data=client.recv(size) 47 m.update(data) # 更新client端的md5 用于后续对比完整性 48 reversed_size+=len(data) # 传了多少长度的数据 49 f.write(data) 50 if recv < file_total_size: # 小于文件长度就继续传,再调用进度条函数 51 recv += len(data) 52 percent = recv / file_total_size 53 progress(percent) 54 else: 55 client_file_md5=m.hexdigest() # 传完后获取接收到数据的md5值 56 print(" file recv done...") 57 server_file_md5=client.recv(1024) # 获取服务器端传的md5 58 if server_file_md5.decode() != client_file_md5: 59 print(‘MD5准确性校验未通过,数据不准确‘) 60 61 client.close()
执行效果:
以上是关于实现简单socket的ftp功能的主要内容,如果未能解决你的问题,请参考以下文章