1. 程式人生 > 實用技巧 >Python網路程式設計(三)-基於tcp協議實現檔案傳輸(解決傳輸大檔案過程中,防止出現粘包現象)

Python網路程式設計(三)-基於tcp協議實現檔案傳輸(解決傳輸大檔案過程中,防止出現粘包現象)

server.py

#服務端接收
#解決傳輸大問題可能出現的粘包現象

import json
import socket
import struct

sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.listen()

conn,addr = sk.accept()
msg_len = conn.recv(4)
#struct.unpack結果是個元組,第一個元素才是具體需要的值。可舉例子看下
dic_len = struct.unpack('i',msg_len)[0]
print(dic_len)
msg = conn.recv(dic_len).decode('
utf-8') msg = json.loads(msg) print(msg['filename'],msg['filesize']) with open(msg['filename'],mode='wb') as f: #針對大檔案,每次傳1024位元組,真實情況下,tcp socket 會自動優化,可能將1024個位元組切分為幾個小檔案, #真實大小則不一定為1024,預設接受方還是會按照1024進行減1024位元組,因此傳送大檔案可能會出問題 #需要減去的是,每次接受到的位元組大小 while msg['filesize'] >0: content
= conn.recv(1024) # msg['filesize'] -= 1024 #減1024,在傳輸資料時候會出問題 # 應減去每次具體收到的位元組大小,才會準確 msg['filesize'] -= len(content) # 寫入內容到指定檔案 f.write(content) conn.close() sk.close()
server端程式碼

client.py

#客戶端傳送
#
import os
import json
import socket
import struct

sk = socket.socket()
sk.connect((
'127.0.0.1',9000)) #需要傳送檔名,檔案大小 # abs_path = r'E:\project\testfile' abs_path = r'F:\web\day43\day43-002 內容回顧.mp4' # os.path模組獲取檔名 filename = os.path.basename(abs_path) # os.path模組獲取檔案大小 filesize = os.path.getsize(abs_path) dic = {'filename':filename,'filesize':filesize} # 網編中傳輸資料,常用的是json型別 str_dic = json.dumps(dic) b_dic = str_dic.encode('utf-8') msg_len = struct.pack('i',len(b_dic)) #傳送4個位元組 表示字典轉換為位元組後的長度 sk.send(msg_len) #傳送具體的字典資料 sk.send(b_dic) with open(abs_path,mode='rb') as f: #針對大檔案 每次傳送1024位元組,總檔案大小減去每次傳送的位元組大小進行while迴圈 while filesize > 0: content = f.read( 1024) # filesize -= 1024 filesize -= len(content) sk.send(content) sk.close()
client端程式碼