1. 程式人生 > 其它 >Python-3 檔案傳輸

Python-3 檔案傳輸

技術標籤:python

  • 檔案傳輸功能(簡單版本)
'''服務端'''
import json
import os
import socket
import struct

share_dir = r'F:\winnie\socket\07_檔案傳輸\server\share'
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(('127.0.0.1', 8090))

phone.listen(5)

print('starting======')
while True:
    conn, client_addr = phone.accept()  # conn是套接字物件
    print(client_addr)
    while True:
        try:
            # 1、收命令
            res = conn.recv(8096)
            if not res: break

            # 2、解析命令,提取響應命令引數
            cmds = res.decode('utf-8').split()
            filename = cmds[1]

            # 3、以讀的方式開啟檔案,讀取檔案內容傳送給客戶端
            # 第一步:製作固定長度的報頭
            header_dict = {
                'filename': filename,
                'md5': 'xxx',
                'file_size': os.path.getsize(r'%s/%s' % (share_dir, filename))
            }
            header_json = json.dumps(header_dict)
            header_bytes = header_json.encode('utf-8')

            # 第二步:先發送報頭的長度
            conn.send(struct.pack('i', len(header_bytes)))

            # 第三步:再發送報頭
            conn.send(header_bytes)

            # 第四步:再發送真實的資料
            with open('%s/%s' % (share_dir, filename), 'rb') as f:
                for line in f:
                    conn.send(line)

        except ConnectionResetError:
            break

    conn.close()

phone.close()
'''客戶端'''
import json
import socket
import struct

download_dir = r'F:\winnie\socket\07_檔案傳輸\client\download'
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

phone.connect(('127.0.0.1', 8090))

while True:
    # 1、發命令
    cmd = input('>>').strip()
    if not cmd: continue
    phone.send(cmd.encode('utf-8'))
    # 2、以寫的方式開啟一個新檔案,接受服務端發來的檔案的內容寫入客戶的新檔案
    # 第一步:先收報頭長度
    obj = phone.recv(4)
    header_size = struct.unpack('i', obj)[0]

    # 第二步:再收報頭
    header_bytes = phone.recv(header_size)

    # 第三步:從報頭中解析處對真實資料的描述資訊
    header_json = header_bytes.decode('utf-8')
    header_dic = json.loads(header_json)

    print(header_dic)
    total_size = header_dic['file_size']
    filename = header_dic['filename']

    # 第四步:接收真實的資料
    with open('%s/%s' % (download_dir, filename), 'wb') as f:
        recv_size = 0
        while recv_size < total_size:
            line = phone.recv(1024)
            f.write(line)
            recv_size += len(line)
            print('總大小:%s  已下載大小:%s' % (total_size, recv_size))

phone.close()

在這裡插入圖片描述

  • 檔案傳輸功能-函式版(優化版本)
'''服務端'''
import json
import os
import socket
import struct

share_dir = r'F:\winnie\socket\07_檔案傳輸\server\share'


def get(conn, cmds):
    filename = cmds[1]

    # 3、以讀的方式開啟檔案,讀取檔案內容傳送給客戶端
    # 第一步:製作固定長度的報頭
    header_dict = {
        'filename': filename,
        'md5': 'xxx',
        'file_size': os.path.getsize(r'%s/%s' % (share_dir, filename))
    }
    header_json = json.dumps(header_dict)
    header_bytes = header_json.encode('utf-8')

    # 第二步:先發送報頭的長度
    conn.send(struct.pack('i', len(header_bytes)))

    # 第三步:再發送報頭
    conn.send(header_bytes)

    # 第四步:再發送真實的資料
    with open('%s/%s' % (share_dir, filename), 'rb') as f:
        for line in f:
            conn.send(line)


def input(conn, cmds):
    pass


def run():
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    phone.bind(('127.0.0.1', 8091))

    phone.listen(5)

    print('starting======')
    while True:
        conn, client_addr = phone.accept()  # conn是套接字物件
        print(client_addr)
        while True:
            try:
                # 1、收命令
                res = conn.recv(8096)
                if not res: break

                # 2、解析命令,提取響應命令引數
                cmds = res.decode('utf-8').split()
                if cmds[0] == 'get':
                    get(conn, cmds)
                elif cmds[0] == 'put':
                    input(conn, cmds)


            except ConnectionResetError:
                break

        conn.close()

    phone.close()


if __name__ == '__main__':
    run()

'''客戶端'''
import json
import socket
import struct

download_dir = r'F:\winnie\socket\07_檔案傳輸\client\download'


def get(phone, cmds):
    # 2、以寫的方式開啟一個新檔案,接受服務端發來的檔案的內容寫入客戶的新檔案
    # 第一步:先收報頭長度
    obj = phone.recv(4)

    header_size = struct.unpack('i', obj)[0]

    # 第二步:再收報頭
    header_bytes = phone.recv(header_size)

    # 第三步:從報頭中解析處對真實資料的描述資訊
    header_json = header_bytes.decode('utf-8')
    header_dic = json.loads(header_json)

    print(header_dic)
    total_size = header_dic['file_size']
    filename = header_dic['filename']

    # 第四步:接收真實的資料
    with open('%s/%s' % (download_dir, filename), 'wb') as f:
        recv_size = 0
        while recv_size < total_size:
            line = phone.recv(1024)
            f.write(line)
            recv_size += len(line)
            print('總大小:%s  已下載大小:%s' % (total_size, recv_size))


def put(phone, cmds):
    pass


def run():
    phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    phone.connect(('127.0.0.1', 8091))

    while True:
        # 1、發命令
        inp = input('>>').strip()
        if not inp: continue
        phone.send(inp.encode('utf-8'))

        cmds = inp.split()
        if cmds[0] == 'get':
            get(phone, cmds)
        elif cmds[0] == 'put':
            put(phone, cmds)
    phone.close()


if __name__ == '__main__':
    run()

  • 檔案傳輸功能-面向物件(升級版)