python——網絡編程之基於TCP協議的文件上傳和下載

在這裏我實現的是客戶端上傳文件,服務器接收文件,如果要實現客戶端從服務器上下載文件的話,直接將代碼反過來即可。廢話不多說,下面直接上代碼吧。

下面是服務器端的代碼

import socket
import struct
import json

sk = socket.socket()
sk.bind(('127.0.0.1', 8888))  # 綁定ip地址和端口
sk.listen()   # 開啓監聽

buffer = 1024  # 緩衝區大小,這裏好像因爲windows的系統的原因,這個接收的緩衝區不能太大

conn, addr = sk.accept()  
# 先接收報頭的長度
head_len = conn.recv(4)
head_len = struct.unpack('i', head_len)[0]  # 將報頭長度解包出來
# 再接收報頭
json_head = conn.recv(head_len).decode('utf-8')   # 拿到的是bytes類型的數據,要進行轉碼
head = json.loads(json_head)   # 拿到原本的報頭
file_size = head['filesize']
with open(head['filename'], 'ab') as f:
    print(file_size)
    while file_size:
        if file_size >= buffer:  # 判斷剩餘文件的大小是否超過buffer
            content = conn.recv(buffer)
            f.write(content)
            file_size -= buffer
        else:
            content = conn.recv(file_size)
            f.write(content)
            file_size = 0
            break
conn.close()
sk.close()

下面是客戶端的代碼

import socket
import os
import json
import struct

sk = socket.socket()
sk.connect(('127.0.0.1', 8888))  # 與服務器建立連接

buffer = 1024
# 定製我們的報頭,這裏的報頭不是唯一的,你可以根據你的想法去更改
head = {'filepath': r'你的文件路徑',
        'filename': r'你要傳的文件名',
        'filesize': None}  
file_path = os.path.join(head['filepath'], head['filename'])
# 計算文件的大小
filesize = os.path.getsize(os.path.join(head['filepath'], head['filename']))  
head['filesize'] = filesize
json_head = json.dumps(head)  # 利用json將字典轉成字符串
bytes_head = json_head.encode('utf-8')    # 字符串轉bytes
# 計算head長度
head_len = len(bytes_head)  # 報頭的長度
# 利用struct將int類型的數據打包成4個字節的byte,所以服務器端接受這個長度的時候可以固定緩衝區大小爲4
pack_len = struct.pack('i', head_len) 
# 先將報頭長度發出去
sk.send(pack_len)
# 再發送bytes類型的報頭
sk.send(bytes_head)
with open(file_path, 'rb') as f:
    while filesize:
        print(filesize)
        if filesize >= buffer:
            content = f.read(buffer)  # 每次讀取buffer字節大小內容
            filesize -= buffer
            sk.send(content)  # 發送讀取的內容
        else:
            content = f.read(filesize)
            sk.send(content)
            filesize = 0
            break
sk.close()

在這個上傳、下載文件的實驗中,發現了一個現象,就是buffer基本不能超過1024字節大小,,如果超過1024的大小就會報錯,這可能與windows操作系統有關,可能是由於讀寫不同步造成的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章