普通函数版
目录结构
settings.ini
[DEFAULT]
share_path = ./share/
Server端代码
"""简单的文件传输
Server端
"""
import hashlib
import json
import os
import socket
import struct
share_path = r'./share/'
def exit_head(args, addr):
head_dc = {
'filename': args,
'filesize': len(args),
'source': socket.gethostbyname(socket.gethostname()),
'destination': str(addr)
}
head_json = json.dumps(head_dc)
head_bytes = bytes(head_json, encoding='utf-8')
head_len = len(head_bytes)
fixed = struct.pack('i', head_len)
return fixed, head_bytes
def make_head(addr, ret):
print(ret)
head_dc = {
'filename': None,
'filesize': None,
'filetype': None,
'md5': None,
'source': None,
'destination': None
}
head_dc['filename'] = ret[1].decode('utf-8')
head_dc['filesize'] = os.path.getsize(os.path.join(share_path, ret[1].decode('utf-8')))
head_dc['filetype'] = os.path.splitext(ret[1])[1].decode('utf-8')
with open(file=share_path + ret[1].decode('utf-8'), mode='rb') as fp:
h = hashlib.md5()
readed_size = 0
while readed_size < head_dc['filesize']:
con = fp.read(1024)
h.update(con)
readed_size += len(con)
head_dc['md5'] = h.hexdigest()
head_dc['source'] = socket.gethostbyname(socket.gethostname())
head_dc['destination'] = str(addr)
head_json = json.dumps(head_dc)
print(head_json)
head_bytes = head_json.encode(encoding='utf-8')
fixed = struct.pack('i', len(head_bytes))
return fixed, head_bytes, head_dc
def get(conn, addr, ret):
fixed, head_bytes, head_dc = make_head(addr, ret)
conn.send(fixed)
conn.send(head_bytes)
with open(file=share_path + ret[1].decode('utf-8'), mode='rb') as fp:
readed_size = 0
while readed_size < head_dc['filesize']:
con = fp.read(1024)
conn.send(con)
readed_size += len(con)
return True
def put():
pass
def analysize(conn, addr):
cmds = conn.recv(1024)
if not cmds:
return -1
if cmds == b'exit':
return cmds
cmd, type = cmds.split(b' ')
return cmd, type
def connect():
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ip_port = ('', 8080)
sk.bind(ip_port)
sk.listen(5)
conn, addr = sk.accept()
return conn, addr
def disconnect(conn):
conn.close()
def judge(*args):
if args[-1][0] == b'get':
status = get(args[0], args[1], args[-1])
else:
status = put()
return status
def main():
while 1:
conn, addr = connect()
conn.send(b'Welcome!')
while 1:
try:
ret = analysize(conn, addr)
if ret is -1:
break
if ret == b'exit':
break
status = judge(conn, addr, ret)
if status:
print('Done!')
else:
print('Failed!')
except ConnectionResetError:
break
disconnect(conn)
pass
if __name__ == '__main__':
main()
Client端代码
"""简单的文件传输
Client端
"""
import hashlib
import json
import os
import socket
import struct
import time
downloads_path = r'./downloads/'
def parse_head(sk):
fixed = sk.recv(4)
head_len = struct.unpack('i', fixed)[0]
head_bytes = sk.recv(head_len)
print(head_bytes.decode('utf-8'))
head_dc = json.loads(head_bytes.decode(encoding='utf-8'))
return head_dc
def get(args):
sk = args[0]
cmds = args[1]
sk.send(cmds.encode(encoding='utf-8'))
head_dc = parse_head(sk)
if head_dc['filename'] == 'exit':
return b'exit'
file_path = f"{downloads_path}{head_dc['filename']}"
received_size = 0
file_size = head_dc['filesize']
dot = '.'
lt = '>'
start = time.perf_counter()
h = hashlib.md5()
with open(file=file_path, mode='wb') as fp:
print('开始下载'.center(100, '='))
while received_size < file_size:
con = sk.recv(1024)
fp.write(con)
h.update(con)
received_size += len(con)
rate = received_size / file_size * 100
tmp = int(rate)
print('\r%%%.2f[%s%s]%.2fs' % (rate, tmp * lt, (100 - tmp) * dot, time.perf_counter() - start), end='')
print()
if h.hexdigest() != head_dc['md5']:
os.remove(file_path)
return False
print('下载结束'.center(100, '='))
return True
def put():
pass
def judge(*args):
ls = args[1].split()
if ls[0] == 'get':
status = get(args)
elif ls[0] == 'put':
status = put()
else:
args[0].send(b'exit')
status = b'exit'
return status
def main():
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
ip_port = ('localhost', 8080)
sk.connect(ip_port)
print(sk.recv(1024).decode(encoding='utf-8'))
while 1:
cmds = input('>>> ').strip()
status = judge(sk, cmds)
if status == b'exit':
break
if status is True:
print('Complete!')
else:
print('Failed!')
pass
if __name__ == '__main__':
main()
面向对象版
目录结构
Server端代码
"""简单的文件传输面向对象版
Server端
"""
import json
import os
import socket
import struct
import time
class MyTCPServer(object):
"""
"""
address_famliy = socket.AF_INET
protocol_type = socket.SOCK_STREAM
reuse_address = True
coding = 'utf-8'
link_queue_size = 5
buffer = 1024
fixed_len_bytes_dc = {
'i': 4,
'l': 8
}
server_dir = r'./share/'
def __init__(self, server_address, bind_activate=True):
self.server_address = server_address
self.socket = socket.socket(family=self.address_famliy,
type=self.protocol_type)
if bind_activate:
try:
self.server_bind()
self.server_activate()
except Exception:
self.server_close()
raise
def server_bind(self):
if self.reuse_address:
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_address)
self.server_address = self.socket.getsockname()
def server_activate(self):
self.socket.listen(self.link_queue_size)
def get_request(self):
conn, addr = self.socket.accept()
return conn, addr
def request_close(self):
self.conn.close()
def server_close(self):
self.socket.close()
pass
def run(self):
while 1:
self.conn, self.addr = self.get_request()
print(f'from client: {self.addr}')
while 1:
try:
head_struct = self.conn.recv(self.fixed_len_bytes_dc['i'])
if not head_struct:break
head_len = struct.unpack('i', head_struct)[0]
head_json = self.conn.recv(head_len).decode(encoding=self.coding)
head_dc = json.loads(head_json)
cmd = head_dc['cmd']
if hasattr(self, cmd):
func = getattr(self, cmd)
func(head_dc)
except ConnectionResetError:
break
self.request_close()
def put(self, args):
file_path = os.path.abspath(os.path.join(self.server_dir, args['filename']))
file_size = args['filesize']
dot = '.'
lt = '>'
start = time.perf_counter()
print('接收开始'.center(100, '='))
with open(file=file_path, mode='wb') as fp:
while 1:
if file_size >= self.buffer:
recv_data = self.conn.recv(self.buffer)
fp.write(recv_data)
file_size -= self.buffer
else:
recv_data = self.conn.recv(file_size)
fp.write(recv_data)
file_size -= file_size
break
scale = (1 - (file_size / args['filesize'])) * 100
print('\r%%%.2f[%s%s]%.2fs' % (scale, int(scale) * lt, (100 - int(scale)) * dot, time.perf_counter() - start), end='')
print()
print('接收完成'.center(100, '='))
server1 = MyTCPServer(('', 8080))
server1.run()
Client端代码
"""简单的文件传输面向对象版
Client端
"""
import json
import os
import socket
import struct
import time
class MyTCPClient(object):
address_family = socket.AF_INET
protocol_type = socket.SOCK_STREAM
reuse_address = True
buffer = 1024
coding = 'utf-8'
client_dir = r'./downloads/'
def __init__(self, server_address, connect=True):
self.server_address = server_address
self.socket = socket.socket(self.address_family,
self.protocol_type)
if connect:
try:
self.client_connect()
except Exception:
self.client_close()
raise
def client_connect(self):
self.socket.connect(self.server_address)
def client_close(self):
self.socket.close()
def run(self):
while True:
inp = input(">>: ").strip()
if not inp:
continue
cmds = inp.split()
cmd = cmds[0]
if hasattr(self, cmd):
func = getattr(self, cmd)
func(cmds)
def put(self, args):
cmd = args[0]
filename = args[1]
filepath = os.path.abspath(os.path.join(self.client_dir, filename))
if not os.path.isfile(filepath):
print('file:%s is not exists' % filename)
return
else:
filesize = os.path.getsize(filepath)
head_dic = {'cmd': cmd, 'filename': os.path.basename(filename), 'filesize': filesize}
print(head_dic)
head_json = json.dumps(head_dic)
head_json_bytes = bytes(head_json, encoding=self.coding)
head_struct = struct.pack('i', len(head_json_bytes))
self.socket.send(head_struct)
self.socket.send(head_json_bytes)
send_size = 0
dot = '.'
lt = '>'
start = time.perf_counter()
print('上传开始'.center(100, '='))
with open(file=filepath, mode='rb') as fp:
while send_size < head_dic['filesize']:
data = fp.read(self.buffer)
self.socket.send(data)
send_size += len(data)
scale = send_size / head_dic['filesize'] * 100
print('\r%%%.2f[%s%s]%.2fs' %
(
scale,
int(scale) * lt,
(100 - int(scale)) * dot,
time.perf_counter() - start
),
end=''
)
print()
client = MyTCPClient(('localhost', 8080))
client.run()