zoukankan      html  css  js  c++  java
  • 实现简单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()

     执行效果:

  • 相关阅读:
    I Hate It
    hdu 2112 HDU Today ( Dijkstra )
    hdu 1280 前m大的数
    hdu 4252 A Famous City
    hdu 2647 Reward
    hdu 2845 Beans
    hdu 3548 Enumerate the Triangles ( 优 化 )
    hdu 3552 I can do it! (贪心)
    HDU 3033 I love sneakers!(分组背包变形)
    hdu 1712 ACboy needs your help 分组背包
  • 原文地址:https://www.cnblogs.com/lijunlin-py/p/13887278.html
Copyright © 2011-2022 走看看