socket實現ftp上傳下載


socket實現ftp文件的上傳和下載

server端代碼:

import socket
import json
import struct
import os
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

soc.bind(('127.0.0.1', 8021))

soc.listen(5)
# 上傳函數
def uploading_file():
    while True:
        try:
            ftp_dir = r'F:\shpython11\pycharmwork\first_project\study_start\day32\ftp_dir'
            if not os.path.isdir(ftp_dir):  # 這個是作為我們上傳了之后的文件放在這個位置,你改成自己本地的
                os.mkdir(ftp_dir)
            head_bytes_len = conn.recv(4)  # 拿到struct后的頭長度

            head_len = struct.unpack('i', head_bytes_len)[0]  # 取出真正的頭長度

            # 拿到真正的頭部內容
            head_bytes = conn.recv(head_len)
            # 反序列化后取出頭
            head = json.loads(head_bytes)

            file_name = head['file_name']
            file_path = os.path.join(ftp_dir,file_name)
            data_len = head['data_len']
            with open(file_path, 'wb') as fw:
                while data_len > 1024:
                    fw.write(conn.recv(1024))
                    data_len -= 1024
                else:
                    fw.write(conn.recv(data_len))
            conn.send(f'上傳文件 {file_name} 成功'.encode('utf8'))
        except Exception:
            break



while True:
    print('等待客戶端連接。。。')
    conn, addr = soc.accept()
    print('客戶端已連接:', addr)
    choice = conn.recv(1).decode('utf8')
    if choice == 'q':
        break
    if choice == '1':
        print('客戶端選擇了ftp上傳服務')
        uploading_file()
    elif choice == '2':
        print('客戶端選擇了ftp下載服務')
        while True:
            try:
                ftp_dir = r'F:\shpython11\pycharmwork\first_project\study_start\day32\ftp_dir'
                if not os.path.isdir(ftp_dir):  # 這個是作為我們上傳了之后的文件放在這個位置,你改成自己本地的
                    os.mkdir(ftp_dir)
                file_list = os.listdir(ftp_dir)
                head = {'file_list': file_list}
                head_bytes = json.dumps(head).encode('utf8')
                head_bytes_len = struct.pack('i', len(head_bytes))

                conn.send(head_bytes_len)
                conn.send(head_bytes)

                client_head_bytes_len = conn.recv(4)

                client_head_len = struct.unpack('i', client_head_bytes_len)[0]
                client_head_bytes = conn.recv(client_head_len)
                client_head = json.loads(client_head_bytes)
                choice = client_head['choice']
                file_name = file_list[int(choice)]

                file_path = os.path.join(ftp_dir, file_name)

                with open(file_path, 'rb') as fr:
                    data = fr.read()

                server_head = {'data_len': len(data), 'file_name': file_name}  # 自定義頭
                server_head_bytes = json.dumps(server_head).encode('utf8')
                server_head_bytes_len = struct.pack('i', len(server_head_bytes))

                conn.send(server_head_bytes_len)
                conn.send(server_head_bytes)
                conn.send(data)
                conn.send(f'下載文件 {file_name} 成功'.encode('utf8'))

            except Exception:
                break

    conn.close()
soc.clone()

client端代碼:

import socket
import os
import struct
import json
client_soc = socket.socket()

client_soc.connect(('127.0.0.1',8021))

# 獲取文件夾下的文件
def get_file_list(file_path):
    if os.path.exists(file_path):
        if os.path.isfile(file_path):
            return True,file_path
        else:
            file_list = os.listdir(file_path)
            if file_list==[]:
                return False,'當前文件夾為空,請重新選擇'
            else:
                return True,file_list
    else:
        return False,'你輸入的文件路徑不對'

# 上傳函數
def uploading_file():
    print('歡迎進入ftp文件上傳系統')
    while True:
        dir_path = input('請輸入文件所在的文件夾路徑或文件路徑(輸入q退出):')

        if dir_path == 'q':
            print('你選擇了退出上傳系統')
            break
        flag, dir_list = get_file_list(dir_path)
        if flag:
            if os.path.isfile(dir_path):
                file_name = dir_path.split('\\')[-1]
                file_path = dir_path
            else:
                for ind, file in enumerate(dir_list):
                    print(f'文件編號:{ind} 對應的文件名為:{file}')
                choice = input('請輸入文件編號進行上傳:').strip()
                choice = int(choice)
                file_name = dir_list[choice]
                file_path = os.path.join(dir_path, file_name)

            with open(file_path,'rb') as fr:
                data = fr.read()
            head = { 'data_len': len(data),'file_name':file_name}  # 自定義頭
            head_bytes = json.dumps(head).encode('utf8')
            head_bytes_len = struct.pack('i',len(head_bytes))

            client_soc.send(head_bytes_len)
            client_soc.send(head_bytes)
            client_soc.send(data)
            msg = client_soc.recv(1024)
            print(msg.decode('utf8'))
        else:
            print('你輸入的文件路徑不存在')

# 下載函數
def download():
    print('歡迎來到ftp下載系統')
    head_bytes_len = client_soc.recv(4)
    head_len = struct.unpack('i', head_bytes_len)[0]
    head_bytes = client_soc.recv(head_len)
    head = json.loads(head_bytes)
    file_list = head['file_list']
    if file_list == []:
        print('當前ftp中無文件可下載,等待上傳中')
    else:
        print('當前ftp中有如下文件')
        for ind,file in enumerate(file_list):
            print(f'文件編號:{ind} 對應的文件名為:{file}')
        choice = input('請選擇要下載文件的編號:')
        choice_head = {'choice':choice}  # 自定義頭

        choice_head_bytes = json.dumps(choice_head).encode('utf8')

        choice_head_bytes_len = struct.pack('i', len(choice_head_bytes))
        client_soc.send(choice_head_bytes_len)
        client_soc.send(choice_head_bytes)

        # 接收用戶傳遞過來的文件
        client_head_bytes_len = client_soc.recv(4)  # 拿到struct后的頭長度

        client_head_len = struct.unpack('i', client_head_bytes_len)[0]  # 取出真正的頭長度
        # 拿到真正的頭部內容
        client_head_bytes = client_soc.recv(client_head_len)
        # 反序列化后取出頭
        client_head = json.loads(client_head_bytes)
        file_name = client_head['file_name']
        data_len = client_head['data_len']

        with open(file_name, 'wb') as fw:
            while data_len > 1024:
                fw.write(client_soc.recv(1024))
                data_len -= 1024
            else:
                fw.write(client_soc.recv(data_len))
        msg = client_soc.recv(1024)
        print(msg.decode('utf8'))


while True:
    msg = '''
    1.文件上傳
    2.文件下載
    q.退出系統
    '''
    print(msg)
    choice = input('請做出你的選擇:').strip()
    client_soc.send(choice.encode('utf8'))
    if choice == 'q':
        print('你選擇了退出系統')
        break
    if choice == '1':
        uploading_file()

    elif choice == '2':
        download()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM