day29 python socket实现文件上传下载功能 socketserver模块

day29 python socket实现文件上传下载功能 socketserver模块   一.写个文件上传的功能(类似于ftp文件上传的功能)     1.上传文件需要考虑先传: 文件信息(包括文件名, 大小, md5, 和上传的动作)     2.上传数据结构的组织: 防止出现黏包的现象(通过构造数据头部信息实现)         上传的数据格式为: json_header+json+data             json_header: 此字段固定长度为4字节(由struct模块实现), 用于取到完整的json             json:此为记录文件信息,记录文件的各种信息             data:通过json中文件长度,取文件的全部数据 #ftp_server   import socket import json import struct import hashlib ip_port = ('127.0.0.1', 65533) server = socket.socket() server.bind(ip_port) server.listen(5) print('ftp_server is running... ...') while 1:     conn, addr = server.accept()     while 1:         json_header = conn.recv(4)         json_header = struct.unpack('i', json_header)[0]         file_info_json = conn.recv(json_header)         file_info_dict = json.loads(file_info_json)         file_name = file_info_dict.get('file_name')         file_size = file_info_dict.get('file_size')         file_md5 = file_info_dict.get('file_md5')         file_operation = file_info_dict.get('file_operation')         if file_operation == 'put':             recv_size = 0             md5 = hashlib.md5(b'bajieaishuishui')             with open('abc'+file_name, mode='wb') as f:      #出现过的问题: 文件19k, 但是接收的文件只有1k,(md5对的: 说明接收到的数据是完整的, 只是写文件的过程中有问题)                 while recv_size < file_size:                 #原因: 是把条件判断写在了文件打开的外面, 导致每次条件判断都先清空文件.最后只留下最后一次接收                     free_size = file_size - recv_size        #解决方法: 条件判断和打开文件动作互换, 得以解决                     if free_size < 1024:                         recv_data = conn.recv(free_size)                     else:                         recv_data = conn.recv(1024)                     recv_size += len(recv_data)                     free_size = file_size - recv_size                     f.write(recv_data)                     md5.update(recv_data)             recv_md5 = md5.hexdigest()             if file_md5 == recv_md5:                 conn.send(b'203')             else:                 conn.send(b'204')                 #上传         elif file_operation == 'get':             #下载             pass     #ftp_client   import socket import json import struct import os import hashlib ip_port = ('127.0.0.1', 65533) 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:     cmds = input('>>> ')                                        #命令: put digit.py     file_name = cmds.strip().split(' ')[1]     file_operation = cmds.strip().split(' ')[0]     file_size = os.path.getsize(file_name)     file_md5 = mymd5(file_name)     file_info_dict = {'file_name':file_name,                       'file_operation':file_operation,                       'file_size':file_size,                       'file_md5':file_md5,                       }     file_info_json = json.dumps(file_info_dict)     json_size = len(file_info_json)     json_header = struct.pack('i',json_size)     client.send(json_header)     client.send(file_info_json.encode('utf-8'))     with open(file_name, mode='rb') as f:         for line in f:             client.send(line)     code = client.recv(1024).decode('utf-8')     if code == '203':         print('full send')     elif code == '204':         print('send error')   二.socketserver模块     1.socketserver的使用         多继承: 灵活 import socketserver ip_port = ('127.0.0.1',65533) class Myserver(socketserver.BaseRequestHandler):                    #自定义一个类     def handle(self):                                               #方法名必须是这个名字         print('socketserver is runing... ...')                      #这里是业务逻辑: 而且 conn 会封给 self.request         while 1:             try:                 data = self.request.recv(1024)                 self.request.send(data+b'bajieaishuishui')             except:                 self.request.close() server = socketserver.ThreadingTCPServer(ip_port, Myserver)          #socket.socket, bind, listen server.serve_forever()                                               #accept     2.解析socketserver的源码       https://www.processon.com/diagraming/5d832015e4b011ca2aa63171       三.ftp练习     1.多用户同时登陆                                    (并发, 用socketserver模块实现)     2.用户登录,加密认证                                 (使用hashlib MD5加密)     3.上传/下载文件, 保证文件的一致性                   (对文件hashlib md5加密)     4.传输过程中实现进度条     5.不同用户家目录不同, 且只能访问自己的家目录        (os.path.join('',username, 'a.txt')     6.对用户进行磁盘配额, 不同用户配额可不同            (上传,下载之前做文件夹大小的判断)     7.用户登录server后, 可在家目录权限下切换子目录      (客户端向服务端发送命令, 服务端执行命令 subprocess.popen)     8.查看当前目录下文件, 新建文件夹                    (dir )     9.删除文件和空文件夹                                (也是执行命令)     10.充分使用面向对象知识                             (类,反射)     11.支持断点续传                                     ()        
上一篇:上海 day28--套接字socket


下一篇:爬虫学习