socket模拟文件下载

--------------------------------------------------普通版

服务端:

import socket
import os,sys
import time
import hashlib
import json
import struct
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import setting

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',8080))
server.listen(5)

while True:
conn,client_addr = server.accept()
while True:
try:
cmds = conn.recv(1024).decode('utf-8').split() #接收命令 get a.txt
#解决粘包问题
#1 报头
dir = os.path.join(setting.server_dir, cmds[1])
header_dict = {'filename':cmds[1],'md5':hashlib.md5(str(time.time()).encode('utf-8')).hexdigest(),'total_size':os.path.getsize(dir)}
header_bytes = json.dumps(header_dict).encode('utf-8')
#2 把报头长度制成固定长度的pack
head_pack = struct.pack('i',len(header_bytes))
#3 发送带有报头长度的固定长度包
conn.send(head_pack)
#4 发送报头
conn.send(header_bytes)
#按行发送内容

with open(dir,'rb') as f:
for line in f:
conn.send(line) #按行发送时发生粘包 按行发送解决了一次读取的占用内存问题 最后发送的内容因粘包实际发送所有结果
except ConnectionResetError:
break
conn.close()

server.close()

客户端:

#get a.txt -》服务端将txt内容写到client文件夹download文件夹下
import socket
import struct
import json
import os,sys,time
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from server import setting

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))

while True:
cmds = input('\n>>>:').strip()
if not cmds:continue
client.send(cmds.encode('utf-8'))

head_pack = struct.unpack('i',client.recv(4)) #带有报头长度的固定长度包
x = head_pack[0] #从固定包pack里获取报头的长度
head_bytes = client.recv(x) #获取报头
head_dict = json.loads(head_bytes.decode('utf-8'))
total_size = head_dict['total_size'] #获取文件数据大小
res_data = b''
dir = os.path.join(setting.client_dir,head_dict['filename'])
while len(res_data) < total_size:
res = client.recv(1024)
res_data += res
# for i in range(1):
# sys.stdout.write('#')
# sys.stdout.flush()
# time.sleep(0.01)
with open(dir,'wb') as f:
f.write(res_data)
# with open(dir,'wb') as f:
# res_size = 0
# while res_size < total_size:
# line = client.recv(1024)
# res_size += len(line)
# f.write(line)

client.close()

猜你喜欢

转载自www.cnblogs.com/ekura/p/9375773.html