day31 python ftp练习

day31 python ftp练习
 
一.网络基础
    租服务器:虚拟机(公有云/私有云:公司内部用/docker:可以事先配置好环境)
    端口范围:
    0<-    well-known    ->254<-    保留unix    ->1024<-     自定义    ->65536
        
二.ftp作业
    1.进度条
        '\r' : 主要实现技术: 不换行输出
import time
print('\r80%',end='')
time.sleep(1)
print('\r90%',end='')
        100%        
import time
 
def func(size,total_size):
    time.sleep(0.1)
    print('\r%s%%' % (int(size/total_size*100),),end='')
 
for i in range(101):
    func(i,100)
        100%|------------------->|
import time
 
def func(size,total_size):
    time.sleep(0.1)
    num = int(size/total_size*100)
    print('\r%s%%|%s>|' % (num,'-'*num,),end='')
 
for i in range(101):
    func(i,100)
        sys模块的stdout
sys.stdout.wtrite()            #往输出设备上写
sys.stdout.flush()             #把写的内容刷新到输出设备上, print()内部就是这个
 
    2.计算文件大小
import os
 
方法一:
size_d = os.stat(r'C:\Users\THINKPAD\PycharmProjects\s15\day05').st_size
size_f = os.stat(r'C:\Users\THINKPAD\PycharmProjects\s15\day05\ae9516e7-4fb1-41da-98a7-04c013778867.jpg').st_size
print(size_d)                 #目录本身的大小: 字节
print(size_f)                 #文件的大小: 字节
 
方法二:
size = os.path.getsize(r'C:\Users\THINKPAD\PycharmProjects\s15\day05\ae9516e7-4fb1-41da-98a7-04c013778867.jpg')
print(size)
 
    
    3.ftp的断点续传
        3.1.1.服务端
import socketserver
import json
import os
ip_port = ('127.0.0.1',65535)
code = {
    '1001':'上传文件,从头开始上传',
    '1002':'断点续传'
}
class MyServer(socketserver.BaseRequestHandler):
    def handle(self):
        #接收client自定义的协议,获取文件的各种信息
        cmd_json = self.request.recv(8192)                   #recv() 最大8k
        cmd_dict = json.loads(cmd_json.decode('utf-8'))
        file_name = cmd_dict.get('file_name')
        file_md5 = cmd_dict.get('file_md5')
        file_path = os.path.join('home', 'bajie', file_name)
        file_md5_path =  os.path.join('home','bajie',file_md5)
        file_size = cmd_dict.get('file_size')
        if not os.path.exists(file_md5_path):               #简单代码往上放
            #直接传,要告诉对方直接传
            response = {'code': '1001'}
            self.request.sendall(json.dumps(response).encode('utf-8'))
            with open(file_md5_path,mode='wb') as f:
                recv_size = 0
                while recv_size < file_size:                #条件的边界不能是等于, 要是等于条件就会一直成立, 一直收
                    data = self.request.recv(1024)
                    recv_size += len(data)
                    f.write(data)                           #实际是写到了内存
                    f.flush()                               #把内存的内容刷到文件
            os.rename(file_md5_path,file_path)              #py2里windows里可能报错,可以使用另外一个模块: import shutil; shutil.move()
        else:
            #断点续传
            exist_size = os.stat(file_md5_path).st_size
            print(exist_size)
            response =  {'code':'1002','exist_size':exist_size}
            self.request.sendall(json.dumps(response).encode('utf-8'))
            with open(file_md5_path,mode='ab') as f:
                recv_size = exist_size
                while recv_size < file_size:                #条件的边界不能是等于, 要是等于条件就会一直成立, 一直收
                    data = self.request.recv(1024)
                    recv_size += len(data)
                    f.write(data)                           #实际是写到了内存
                    f.flush()
            os.rename(file_md5_path, file_path)             # py2里windows里可能报错,可以使用另外一个模块: import shutil;  shutil.move()
if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(ip_port, MyServer)
    server.serve_forever()
        3.1.2.客户端
import socket
import json
import hashlib
import os
ip_port = ('127.0.0.1',65535)
def mymd5(filename):
    md5 = hashlib.md5(b'bajieaishuishui')
    with open(filename, mode='rb') as f:
        for line in f:
            md5.update(line)
        else:
            return md5.hexdigest()
client = socket.socket()
client.connect(ip_port)
while 1:
    cmd = input('please input command: ')                   #定义你自己的协议
    #准备文件各种信息, 自定义协议
    file_path = 'range.py'
    file_name = os.path.basename(file_path)
    file_size = os.stat(file_path).st_size
    file_md5 = mymd5(file_path)
    cmd_dict = {
        'cmd':'upload',
        'file_name':file_name,
        'file_size':file_size,
        'file_md5':file_md5
    }
    cmd_json = json.dumps(cmd_dict)
    client.sendall(cmd_json.encode('utf-8'))                 #send 和 sendall 一样, sendall一直发, 如果没发完就接着发,推荐有这个
    #等待服务端响应
    response = json.loads(client.recv(8192).decode('utf-8'))
    if response.get('code') == '1001':
        print('从头开始')
        with open(file_path, mode='rb') as f:
            send_size = 0
            while send_size < file_size:                    #文件大小的边界,不应等于, 要是等于, 那等于时条件一直成立, 死循环
                data = f.read(1024)                         #用for每次发一行也行,但是用while这个可以控制发多少
                #data = f.read(66)
                send_size += len(data)
                client.sendall(data)
                #break
    else:
        print('断点续传')
        exist_size = response.get('exist_size')
        send_size = exist_size
        with open(file_path, mode='rb') as f:
            f.seek(exist_size)
            data = f.read(1024)
            send_size += len(data)
            client.sendall(data)    
 
        3.2.1.服务端简化代码:(功能放入函数)
import socketserver
import json
import os
ip_port = ('127.0.0.1',65535)
code = {
    '1001':'上传文件,从头开始上传',
    '1002':'断点续传'
}
def recv_file(file_md5_path,exist_size,file_size,conn,file_path):
    with open(file_md5_path, mode='ab') as f:
        recv_size = exist_size
        while recv_size < file_size:                        #条件的边界不能是等于, 要是等于条件就会一直成立, 一直收
            data = conn.recv(1024)
            recv_size += len(data)
            f.write(data)  # 实际是写到了内存
            f.flush()
 
    if os.path.exists(file_path):
    i = 1
    while True:
        new_file_path = file_path + '.' + str(i)
        print(new_file_path)
        if os.path.exists(new_file_path):
            i += 1
        else:
            os.rename(file_md5_path, new_file_path)          # py2里windows里可能报错,可以使用另外一个模块: import shutil; shutil.move()
            break
    else:
        os.rename(file_md5_path, file_path)
 
def upload(cmd_dict,conn,username):
    file_name = cmd_dict.get('file_name')
    file_md5 = cmd_dict.get('file_md5')
    file_path = os.path.join('home', username, file_name)
    file_md5_path = os.path.join('home', username, file_md5)
    file_size = cmd_dict.get('file_size')
    if not os.path.exists(file_md5_path):                       # 简单代码往上放
        # 直接传,要告诉对方直接传
        exist_size = 0
        response = {'code': '1001'}
    else:
        # 断点续传
        exist_size = os.stat(file_md5_path).st_size
        response = {'code': '1002', 'exist_size': exist_size}
    conn.sendall(json.dumps(response).encode('utf-8'))
    recv_file(file_md5_path, exist_size, file_size, conn, file_path)
 
class MyServer(socketserver.BaseRequestHandler):
    def handle(self):
        #接收client自定义的协议,获取文件的各种信息
        cmd_json = self.request.recv(8192)                          #recv() 最大8k
        cmd_dict = json.loads(cmd_json.decode('utf-8'))
        file_cmd = cmd_dict.get('cmd')
        if file_cmd == 'upload':
            upload(cmd_dict,self.request,'bajie')
        elif file_cmd == 'download':
            pass
if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(ip_port, MyServer)
    server.serve_forever()
        3.2.2.客户端代码简化(把功能放入函数中)
import socket
import json
import hashlib
import os
ip_port = ('127.0.0.1',65535)
def func(size,total_size):
    num = int(size/total_size*100)
    print('\r%s%%|%s>|' % (num,'-'*num,),end='')
def mymd5(filename):
    md5 = hashlib.md5(b'bajieaishuishui')
    with open(filename, mode='rb') as f:
        for line in f:
            md5.update(line)
        else:
            return md5.hexdigest()
def send_file(exist_size,file_size):
    with open(file_path, mode='rb') as f:
        f.seek(exist_size)
        send_size = exist_size
        while send_size < file_size:
            data = f.read(1024)
            send_size += len(data)
            client.sendall(data)
            func(send_size,file_size)
        print()
def upload(file_path):
    # 准备文件各种信息, 自定义协议
    file_name = os.path.basename(file_path)
    file_size = os.stat(file_path).st_size
    file_md5 = mymd5(file_path)
    cmd_dict = {
        'cmd': 'upload',
        'file_name': file_name,
        'file_size': file_size,
        'file_md5': file_md5
    }
    cmd_json = json.dumps(cmd_dict)
    client.sendall(cmd_json.encode('utf-8'))  # send 和 sendall 一样, sendall一直发, 如果没发完就接着发,推荐用这个
    # 等待服务端响应
    response = json.loads(client.recv(8192).decode('utf-8'))
    print(response)
    if response.get('code') == '1001':
        # 从头开始
        print('从头开始')
        exist_size = 0
    else:
        # 断点续传
        print('断点续传')
        exist_size = response.get('exist_size')
    send_file(exist_size,file_size)
client = socket.socket()
client.connect(ip_port)
while 1:
    user_input = input('please input command: ')   #upload range.py
    cmd,file_path = user_input.split()
    if cmd == 'upload':
        upload(file_path)
    elif cmd == 'download':
        pass
 
4.搭建框架(上面写的叫做脚本, 不叫程序)
    应该创建两个project
        4.1.一个ftp_server
            bin
                start.py
from core.handler import run
if __name__ == '__main__':
    run()
            setting(config)
                config.py
ip_port = ('127.0.0.1',65535)
code = {
    '1001':'上传文件,从头开始上传',
    '1002':'断点续传'
}
            core(src:java习惯用这个,都可以)
                handler.py(文件名也不要大写)
import socketserver
import json
import os
import logging
class Action:
    def __init__(self):
        self.username = None
    def login(self,cmd_dict,conn):
        pass
        self.username = 'bajie'
    def recv_file(self,file_md5_path,exist_size,file_size,conn,file_path):
        with open(file_md5_path, mode='ab') as f:
            recv_size = exist_size
            while recv_size < file_size:  # 条件的边界不能是等于, 要是等于条件就会一直成立, 一直收
                data = conn.recv(1024)
                recv_size += len(data)
                f.write(data)  # 实际是写到了内存
                f.flush()
        if os.path.exists(file_path):
            i = 1
            while True:
                new_file_path = file_path + '.' + str(i)
                print(new_file_path)
                if os.path.exists(new_file_path):
                    i += 1
                else:
                    os.rename(file_md5_path, new_file_path)  # py2里windows里可能报错,可以使用另外一个模块: import shutil; shutil.move()
                    break
        else:
            os.rename(file_md5_path, file_path)
    def upload(self,cmd_dict,conn,username):
        file_name = cmd_dict.get('file_name')
        file_md5 = cmd_dict.get('file_md5')
        file_path = os.path.join('home', username, file_name)
        file_md5_path = os.path.join('home', username, file_md5)
        file_size = cmd_dict.get('file_size')
        if not os.path.exists(file_md5_path):  # 简单代码往上放
            # 直接传,要告诉对方直接传
            exist_size = 0
            response = {'code': '1001'}
        else:
            # 断点续传
            exist_size = os.stat(file_md5_path).st_size
            response = {'code': '1002', 'exist_size': exist_size}
        conn.sendall(json.dumps(response).encode('utf-8'))
        self.recv_file(file_md5_path, exist_size, file_size, conn, file_path)
    def download(self):
        pass
class MyServer(socketserver.BaseRequestHandler):
    def handle(self):
        #接收client自定义的协议,获取文件的各种信息
        cmd_json = self.request.recv(8192)                  #recv() 最大8k
        cmd_dict = json.loads(cmd_json.decode('utf-8'))
        file_cmd = cmd_dict.get('cmd')
        action = Action()
        if action.username: #已登录
            action_name = cmd_dict.get('file_cmd')
            if hasattr(action, action_name):
                getattr(action, action_name)(cmd_dict,self.request)
            else:
                print('cmd is not support')
        else:
            action.login(cmd_dict,self.request)
def run():
    server = socketserver.ThreadingTCPServer(ip_port, MyServer)
    server.serve_forever()
            db(数据库一定不能和代码放到一起:现在是因为还没学数据库)
            log
            readme:如何使用你的程序
            
        4.2.一个ftp_client    (python中:文件夹和文件名推荐用小写, 如果小写不能满足你, 那么可以用下划线分隔)
 
 
课外题:
    让python读取excel文件
 
 
 
 
 
 

猜你喜欢

转载自www.cnblogs.com/aiaii/p/12218098.html
今日推荐