ftp

微笑、不失礼 提交于 2019-11-29 17:23:28

severce

 

 

 

# -*- coding:utf-8 -*-
from threading import Thread
import socket
from core.main import put_file,get_comand
from conf import setting
def handle(conn):
    path = setting.PATH
    conn.send("True".encode(setting.coding))
    while 1:
        try:
            comand_input = conn.recv(setting.BUFFER_SIZE).decode(setting.coding)
            comand_list = get_comand(comand_input)
            comand = comand_list[0]
            option = comand_list[1]
            if comand == 'exit':
                return
            elif comand == "put":
                put_file(path,conn)
        except Exception as e:
            print (e)
            return



def serve_run():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((setting.IP, setting.PORT))
    server_socket.listen(setting.MAX_NUM)
    print ('service starting.........')
    while True:
        try:
            conn, addr = server_socket.accept()
            t = Thread(target=handle, args=(conn,))
            t.start()
        except Exception as e:
            print (e)
            continue
socket_service.py

 

# -*- coding:utf-8 -*-
import os
BASEDIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SAVE_FILE_DIR=os.path.join(BASEDIR,"db")
IP="10.0.0.128"
PORT=9009
BUFFER_SIZE=10240
# 文件保存路径
PATH = r'' or SAVE_FILE_DIR
# coding= "gbk" if os.name == "nt" else "utf-8"
coding = "utf-8"
# 最大监听数
MAX_NUM = 5

# 超时时间
socket_timeout=60
setting.py

 

# -*- coding:utf-8 -*-
from conf import setting
import hashlib
import json, os, struct


def get_comand(userinput):
    if userinput == 'exit':
        return (userinput,'')
    elif userinput and " " in userinput:
        comand_list = userinput.split(" ")
        comand = comand_list[0]
        option = comand_list[1]
        return (comand, option)
    else:
        return 0, 0


def check_file(path):
    if os.path.isfile(path):
        return True
    return False


def check_dir(path):
    if os.path.isdir(path):
        return True
    return False


def GetFileMd5(file_dir):
    myhash = hashlib.md5()
    with open(file_dir, 'rb') as f:
        for line in f:
            myhash.update(line)
    return myhash.hexdigest()


def check_md5(file_dir, file_size):
    myhash = hashlib.md5()
    with open(file_dir, 'rb') as f:
        while file_size:
            if file_size > setting.BUFFER_SIZE:
                line = f.read(setting.BUFFER_SIZE)
                myhash.update(line)
                file_size -= setting.BUFFER_SIZE
            else:
                line = f.read(file_size)
                myhash.update(line)
                file_size = 0
    return myhash.hexdigest()


def write_file_wb(file_dir, conn, data_len, cilent_file_md5):
    with open(file_dir, 'wb') as f:
        while data_len:
            if data_len >= setting.BUFFER_SIZE:
                content = conn.recv(setting.BUFFER_SIZE)
                f.write(content)
                data_len -= setting.BUFFER_SIZE
            else:
                content = conn.recv(data_len)
                f.write(content)
                data_len = 0
    # 校验,一致就发1
    server_file_md5 = GetFileMd5(file_dir)
    if cilent_file_md5 == server_file_md5:
        conn.send("1".encode(setting.coding))
    else:
        conn.send("0".encode(setting.coding))


def put_file(path, conn):
    # 客户端发送的文件会先本地判断是否存在,存在发1 告诉服务器可以接收了
    head = conn.recv(4)  # 先收4个bytes,这里4个bytes里包含了报头的长度
    head_json_len = struct.unpack('i', head)[0]  # 解出报头的长度
    head = json.loads(conn.recv(head_json_len).decode(setting.coding))  # 拿到报头
    # 获取文件长度,名字
    data_len = head['file_size']  # 取出报头内包含的信息
    file_name = head["file_name"]
    cilent_file_md5 = head["cilent_file_md5"]
    file_dir = os.path.join(path, file_name)
    # 首先先判断服务端是否有同名文件
    if os.path.isfile(file_dir):
        server_file_md5 = GetFileMd5(file_dir)
        # 判断服务端和客户端的文件是否一致
        # 如果一致不需要上传
        if server_file_md5 == cilent_file_md5:
            print("不需要上传文件了\n")
            conn.send("2".encode(setting.coding))
        else:
            conn.send("3".encode(setting.coding))
            choice = conn.recv(1).decode(setting.coding)
            if choice == '0':
                return
    conn.send("1".encode(setting.coding))
    write_file_wb(file_dir, conn, data_len, cilent_file_md5)
main.py
# -*- coding:utf-8 -*-

from bin import socket_service

if __name__ == "__main__":
    socket_service.serve_run()
server_start.py

 

client

 

 

# -*- coding:utf-8 -*-
import os
import socket
from conf import setting
from core.main import put_file


def cilent_handle():
    cilent = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    cilent.connect((setting.IP, setting.PORT))
    status = cilent.recv(4).decode(setting.coding)
    while status:
        print ('上传文件 如:put D:\\test.txt')
        print ('退出 exit')
        input_info = raw_input("请输入操作命令:").strip()
        if not ('exit' in input_info or 'put ' in input_info):
            print("命令输入错误\n")
            continue
        cilent.send(input_info.encode(setting.coding))
        if "exit" in input_info:
            cilent.close()
            return False
        elif "put" in input_info:
            file = input_info.rsplit(' ')[-1]
            if os.path.isfile(file):
                put_file(file, cilent)
cilent_handle.py

 

# -*- coding:utf-8 -*-
import os
# BASEDIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# LocalDb=os.path.join(BASEDIR,"Download")
IP="10.0.0.128"
PORT=9009
BUFFER_SIZE=10240

# coding= "gbk" if os.name == "nt" else "utf-8"
coding = "utf-8"
setting.py

 

# -*- coding:utf-8 -*-
import hashlib
import math
import sys
import os, json, struct
from conf import setting
from time import sleep


# 进度条
def progressbar(cur, total):
    percent = '%d%%' % ((float(cur) / total) * 100)
    sys.stdout.write('\r')
    sys.stdout.write('[%-50s] %s' % ('=' * int(math.floor(cur * 50 / total)), percent))
    sys.stdout.flush()
    if cur == total:
        sys.stdout.write('\n')


def GetFileMd5(file_dir):
    myhash = hashlib.md5()
    with open(file_dir, 'rb') as f:
        for line in f:
            myhash.update(line)
    return myhash.hexdigest()


def send_head(file_dir, filesize, cilent):
    file_name = os.path.split(file_dir)[1]
    header_obj = {"file_name": file_name, "file_size": filesize}
    header_json = json.dumps(header_obj)
    head_json_bytes = bytes(header_json, encoding=setting.coding)
    cilent.send(struct.pack('i', len(head_json_bytes)))
    cilent.send(head_json_bytes)
    print(file_name)


# 封装数据,然后将数据发到服务器
def packege_head(cilent, file_path, filesize):
    file_name = os.path.split(file_path)[1]
    cilent_file_md5 = GetFileMd5(file_path)
    header_obj = {"file_name": file_name, "file_size": filesize, "cilent_file_md5": cilent_file_md5}
    header_json = json.dumps(header_obj)
    head_json_bytes = bytes(header_json)  # , encoding=setting.coding
    # 发送数据
    sleep(0.5)
    cilent.send(struct.pack('i', len(head_json_bytes)))
    cilent.send(head_json_bytes)


def write_file(file_dir, data_len, cilent):
    recv_size = 0
    total_size = data_len
    with open(file_dir, 'wb') as f:
        while data_len:
            if data_len >= setting.BUFFER_SIZE:
                content = cilent.recv(setting.BUFFER_SIZE)
                f.write(content)
                data_len -= setting.BUFFER_SIZE
                recv_size += setting.BUFFER_SIZE
                progressbar(recv_size, total_size)
            else:
                content = cilent.recv(data_len)
                f.write(content)
                recv_size += data_len
                progressbar(recv_size, total_size)
                data_len = 0


def read_file(file_dir, filesize, cilent):
    send_size = 0
    total_size = filesize
    with open(file_dir, 'rb') as f:
        # 读取文件 发送文件
        while filesize:
            if filesize >= setting.BUFFER_SIZE:
                content = f.read(setting.BUFFER_SIZE)
                cilent.send(content)
                filesize -= setting.BUFFER_SIZE
                send_size += setting.BUFFER_SIZE
                progressbar(send_size, total_size)
            else:
                content = f.read(filesize)
                cilent.send(content)
                send_size += filesize
                progressbar(send_size, total_size)
                filesize = 0


def put_file(file_path, cilent):
    print ("开始上传%s" % file_path)
    if os.path.isfile(r"%s" % file_path):
        filesize = os.path.getsize(file_path)
        # 封装数据,然后将数据发到服务器
        packege_head(cilent, file_path, filesize)
        status_code = cilent.recv(1).decode(setting.coding)
        # 服务器返回状态,1表示已经准备好了
        if status_code == "1":
            # 发送数据
            read_file(file_path, filesize, cilent)
            # 接收服务端返回的校验结果
            status = cilent.recv(setting.BUFFER_SIZE).decode(setting.coding)
            if status == "1":
                print("文件上传成功\n")
            if status == "0":
                print("文件上传失败\n")
        elif status_code == "2":
            print("服务端文件已存在,无需重复上传\n")
        elif status_code == '3':
            print ('已存在相同名的文件,继续上传输入1,否则输入0')
            while 1:
                choice = raw_input(': ')
                if choice not in ['1', '0']:
                    print ('请输入正确选项')
                else:
                    break
            cilent.send(choice.encode(setting.coding))
            if choice == '1':
                cilent.send('1'.encode(setting.coding))
                read_file(file_path, filesize, cilent)
                # 接收服务端返回的校验结果
                status = cilent.recv(setting.BUFFER_SIZE).decode(setting.coding)
    else:
        print("文件不存在\n")
        cilent.send("0".encode(setting.coding))
main.py

 

# -*- coding:utf-8 -*-
from bin.socket_cilent import cilent_handle
import sys
reload(sys)
sys.setdefaultencoding('utf8')

if __name__ == "__main__":
    cilent_handle()
client.py

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!