Python-3 檔案傳輸
阿新 • • 發佈:2021-02-02
技術標籤: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()
- 檔案傳輸功能-面向物件(升級版)