上传下载优化版本
server------------
#!/usr/bin/env python
# encoding: utf-8
# Date: 2018/6/7
import socket
import os
import json
import struct
shar_dir = r'E:\python\PycharmProjects\python.base.demo\model3\socket1\上传下载\优化版本\server\share'
def put(conn, cmds):
obj = conn.recv(4)
header_size = struct.unpack('i', obj)[0]
# 2.2收报头
header_bytes = conn.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']
# 2.4,接收真实的数据
with open('%s/%s' % (shar_dir, filename), 'wb') as f: # 服务端打开读方式,这里这种wb方式容易卡主
recv_size = 0
while recv_size < total_size:
line = conn.recv(1024)
f.write(line)
recv_size += len(line)
print('总大小:%s 已上传大小: %s' % (total_size, recv_size))
def get(conn, cmds):
filename = cmds[1]
# 3,易读的方式打开文件,读取文件内容发送给客户端
header_dic = {
'filename': filename,
'md5': 'xxxdxxx',
'file_size': os.path.getsize(r'%s/%s' % (shar_dir, filename))
}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode('utf-8')
# 2,先发送报头的长度
conn.send(struct.pack('i', len(header_bytes)))
# 3,再发报头
conn.send(header_bytes)
# 4,再发送真实的数据
with open('%s/%s' % (shar_dir, filename), 'rb') as f:
# conn.send(f.read())
for line in f:
conn.send(line)
def run():
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.bind(('127.0.0.1', 9909))
phone.listen(5)
print('starting...')
while True:
conn, client_addr = phone.accept()
print(client_addr)
while True:
try:
# 1收命令
res = conn.recv(8096) # b'get a.txt'
if not res:break
# 2,解析命令,提取相应命令参数
cmds = res.decode('utf-8').split() # ['get',filename]
if cmds[0] == 'get':
get(conn, cmds)
elif cmds[0] == 'put':
put(conn, cmds)
except ConnectionResetError:
break
conn.close()
phone.close()
if __name__ == '__main__':
run()
client--------------------
#!/usr/bin/env python
# encoding: utf-8
# Date: 2018/6/7
import socket
import struct
import json
import os
dow_dir = r'E:\python\PycharmProjects\python.base.demo\model3\socket1\上传下载\优化版本\client\download'
def put(phone, cmds):
filename = cmds[1]
# 3,易读的方式打开文件,读取文件内容发送给客户端
header_dic = {
'filename': filename,
'md5': 'xxxdxxx',
'file_size': os.path.getsize(r'%s/%s' % (dow_dir, filename))
}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode('utf-8')
# 2,先发送报头的长度
phone.send(struct.pack('i', len(header_bytes)))
# 3,再发报头
phone.send(header_bytes)
# 4,再发送真实的数据
with open('%s/%s' % (dow_dir, filename), 'rb') as f:
# conn.send(f.read())
for line in f:
phone.send(line)
def get(phone, cmds):
# 2,以写的方式打开一个新文件
# 2.1收报头长度
obj = phone.recv(4)
header_size = struct.unpack('i', obj)[0]
# 2.2收报头
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']
# 2.4,接收真实的数据
with open('%s/%s' % (dow_dir, filename), 'wb') as f: # 服务端打开读方式,这里这种wb方式容易卡主
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 run():
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(('127.0.0.1', 9909))
while True:
# 1,发命令
cmd = input('>>:').strip()
if not cmd:continue
phone.send(cmd.encode('utf-8'))
cmds = cmd.split()
if cmds[0] == 'get':
get(phone, cmds)
elif cmds[0] == 'put':
put(phone, cmds)
phone.close()
if __name__ == '__main__':
run()