基于socket协议实现并发、断点续传

一、配置文件

import os,sys
BASE_PATH=os.path.dirname(os.path.abspath(__file__))
print(BASE_PATH)
DB_PATH=os.path.join(BASE_PATH,'db')
CLIENT_PATH=os.path.join(DB_PATH,'client')
SERVER_PATH=os.path.join(DB_PATH,'server')

HOSTPORT=('127.0.0.1',8021)

二、客户端

import settings
import socket
import os
import struct


def is_exsits(file_name):
    file_name_path= os.path.join(settings.CLIENT_PATH,file_name)
    if os.path.exists(file_name_path):
        file_size=os.path.getsize(file_name_path)
        return (file_name,file_size)
    else:
        return (file_name,0)
def save(data,file_name):
    file_name_path=os.path.join(settings.CLIENT_PATH,file_name)
    with open(file_name_path,'ab')as fw:
        fw.write(data)

def MyClient():
    client = socket.socket()
    client.connect(settings.HOSTPORT)
    while True:
        try:
            client.send('ls'.encode('utf8'))
            server_file_list = eval(client.recv(1024).decode('utf-8'))
            print(server_file_list)
            for index, value in enumerate(server_file_list):
                print(f"{index}:{value}")
            choice = int(input('select index:'))

            file_name = server_file_list[choice]
            file_info_tuple = is_exsits(file_name)
            print(file_info_tuple)
            client.send(str(file_info_tuple).encode('utf8'))
            file_size_struct = client.recv(4)
            file_size = struct.unpack('i', file_size_struct)[0]
            print(file_size)
            if file_size==0:
                MyClient()
            init_size = 0
            while init_size <= file_size:
                data = client.recv(10240)
                init_size += 10240
                save(data, file_name)
            print('上传完毕')
            MyClient()
        except ConnectionError:
            MyClient()

if __name__ == '__main__':
    MyClient()

三、服务端

import socketserver
import settings
import os
import struct


class MyHander(socketserver.BaseRequestHandler):
    @staticmethod
    def get_content_list():
        server_file_dir_path=settings.SERVER_PATH
        return os.listdir(server_file_dir_path)
    @staticmethod
    def get_file_content(file_name):
        file_name_path=os.path.join(settings.SERVER_PATH,file_name)
        with open(file_name_path,'rb')as fr:
            file_content=fr.read()
            return file_content
    @staticmethod

    def get_file_content_iter(file_name,file_size):
        file_name_path=os.path.join(settings.SERVER_PATH,file_name)
        with open(file_name_path,'rb')as fr:
            fr.seek(file_size,0)
            while True:
                data=fr.read(10240)
                yield data
    @staticmethod
    def get_file_size(file_name,file_size):
        file_name_path=os.path.join(settings.SERVER_PATH,file_name)

        file_size=os.path.getsize(file_name_path)-file_size
        print(file_size)
        return struct.pack('i',file_size)

    def handle(self):
        while True:
            print('链接成功')
            try:
                choice_info = self.request.recv(1024).decode('utf8')
                print(choice_info)
                if choice_info == 'ls':
                    server_file_list = self.get_content_list()
                    print(server_file_list)
                    self.request.send(str(server_file_list).encode('utf8'))
                file_name, file_size = eval(self.request.recv(1024).decode('utf8'))
                print(file_name,file_size)
                file_content = self.get_file_content(file_name)
                file_num_struct = self.get_file_size(file_name, file_size)
                print(file_num_struct)
                self.request.send(file_num_struct)
                file_content_iter_obj = self.get_file_content_iter(file_name, file_size)
                for content in file_content_iter_obj:
                    self.request.send(content)
            except ConnectionResetError:
                    break
        self.request.close()

if __name__ == '__main__':
  server=socketserver.ThreadingTCPServer(settings.HOSTPORT,MyHander,bind_and_activate=True)
    server.serve_forever()

posted @ 2019-07-02 17:37  emos  阅读(564)  评论(0编辑  收藏  举报