server
import socket
import struct
import hashlib
import os
host = '127.0.0.1'
port = 8080
buffer_size = 1024
head_strut = '128sq32s' #格式 file_name, file_size, md5 128+8+32
path = '/Users/apple/Desktop/test.mp4'
info_size = struct.calcsize(head_strut)
#md5的编译
def compile_md5(path):
file_size = os.path.getsize(path)
md5 = hashlib.md5()
readed_size = 0
with open(path, 'rb') as f:
while readed_size < file_size:
remain_size = file_size - readed_size
read_size = buffer_size if buffer_size < remain_size else remain_size
readed_size += read_size
md5.update(f.read(read_size))
md = md5.hexdigest()
return md
#将struct翻译回来
def unpack_recv(recv_info):
file_name, file_size, md5 = struct.unpack(head_strut, recv_info)
return file_name, file_size, md5
def main():
sk = socket.socket()
sever_address = (host, port)
sk.bind(sever_address)
sk.listen()
conn, addr = sk.accept()
print('端口{}客户端连接成功'.format(addr[1]))
recv_info = conn.recv(info_size) # 接收长度信息
file_name, file_size, md5_info = unpack_recv(recv_info)
recved_size = 0
with open(path, 'wb') as f:
while recved_size < file_size:
remain_size = file_size - recved_size
recv_size = buffer_size if buffer_size < remain_size else remain_size
recved_size += recv_size
info = conn.recv(recv_size) #接收相应长度的数据
f.write(info) #将接受的数据写入指定位置
md5 = compile_md5(path)
if md5 == md5_info.decode('utf-8'):
print('文件校验正确,确认传输完成!')
else:
print('文件校验失败!', md5)
conn.close()
sk.close()
if __name__ == '__main__':
main()
------------------------------------------------
------------------------------------------------
#client
import socket
import struct
import os
import hashlib
host = '127.0.0.1'
port = 8080
head_struct = '128sq32s'
buffer_size = 1024
path = '/Users/apple/Desktop/vido/day33/03 python fullstack s9day33 黏包现象.mp4'
#过去md5
def get_md5(path):
file_size = os.path.getsize(path)
md5 = hashlib.md5()
readed_size = 0
with open(path, 'rb') as f:
while readed_size < file_size:
remain_size = file_size - readed_size
read_size = buffer_size if buffer_size < remain_size else remain_size
readed_size += read_size
md5.update(f.read(read_size))
md = md5.hexdigest()
return md
#获取file_name, file_size, md5值
def get_value(path):
file_name = os.path.basename(path)
file_size = os.path.getsize(path)
md = get_md5(path)
return file_name, file_size, md
def main():
sk = socket.socket()
sk.connect((host, port))
file_name, file_size, md = get_value(path)
print(type(file_name), type(file_size), type(md))
struct_info = struct.pack(head_struct, bytes(file_name, encoding='utf-8'), file_size, bytes(md, encoding='utf-8'))
sk.send(struct_info)
sended_size = 0
with open(path, 'rb') as f:
while sended_size < file_size:
remain_size = file_size - sended_size
send_size = buffer_size if buffer_size < remain_size else buffer_size
sended_size += send_size
send_info = f.read(send_size)
sk.send(send_info)
print('文件传输结束', md)
sk.close()
if __name__ == '__main__':
main()