本文是基于https://blog.csdn.net/qq_44801116/article/details/100591974上篇,继续深入
一、服务端
1.代码特点
本端代码只是在处理数据上不同。
主要处理是:
接收客户端要下载的文件,并剥离出文件名
打开文件,逐行发送数据
增加MD5校验
2.具体代码
import socket
import os
import hashlib
#第一步:准备工作
server = socket.socket()#声明一个IPv4、使用TCP/IP协议的socket实例
server.bind((“localhost”,8888))#绑定一个监听端口
server.listen(5)#确定最多可以监听多少个客户端
m= hashlib.md5()
#第二步:不断等待消息到来,并进行处理
while True: #第一层大循环:不断接听不同客户端打来的电话(此处拿打电话进行比喻)
conn,addr = server.accept()#标记每个打电话来的人是谁
while True:#第二层小循环:和某一客户端反复进行沟通,像打电话挂断后,再换一下一个客户
receive_data = conn.recv(1024)#设置一次最大可以接受接收多少字节
#判断一下本次接收是否空消息,空消息意味着客户端挂掉了
#如果文件路径不存,则提示文件路径不存在
if not receive_data:
print("客户端断开了。。。。。。。。。。。")
break
#如果客户端未断开进行处理信息
filename = receive_data.split(b" ")[1]
if os.path.isfile(filename):
# 文件的长度(长度是方便客户端判断是否接收完)
file_total_size = os.stat(filename).st_size
conn.send(str(file_total_size).encode())
#为避免粘包现象,添加一个客户端接收确认消息
client_ack = conn.recv(1024)
#为避免大文件占据内存,逐行进行读取发送
f = open(filename, "rb")
for line in f:
conn.send(line)
m.update(line)
f.close()
conn.send(m.hexdigest().encode())
else:
print("好家伙您输入的不是个能打开的玩意儿啊")
print("不好意思了,您嘞,下一位有请")
server.close()
二、客户端
1.代码特点
避免服务端在发送文件和最后发送MD5文件时粘包,增加长度的处理-只接收文件大小的长度,其余的不收。
MD5文件校验(可后续进一步优化)
2.具体代码
import socket
import hashlib
#第一步:准备
client = socket.socket()
client.connect((“localhost”,8888))
#第二步:与服务端进行交互
while True:
input_cmd = input(“请输入文件:”).strip()
#检测一下是否输入,如果没有输入命令,提示请输入命令
if len(input_cmd) == 0:
continue
if input_cmd.startswith("load"):
##1.开始发送文件名称喽
client.send(input_cmd.encode("utf-8"))#发送输入的命令给服务器端
##2.接收文件的长度了
rec_res_size = client.recv(1024)
client.send("接收到文件的数据长度了".encode())
file_tatal_size = int(rec_res_size.decode())
##3.逐行接收文件的内容了哦
received_size = 0
filename = input_cmd.split(" ")[1]
f = open(filename+"副件","wb")
m = hashlib.md5()
#确保客户端可以一次性全部接受服务器发送过来的消息
while received_size < file_tatal_size:#rec_all_data接收所有数据以后再一次性展示
###避免服务端含有md5的信息,故针对最后一次接收数据进行1024的判断
if file_tatal_size-received_size > 1024:
data = client.recv(1024)
else:
data = client.recv(file_tatal_size-received_size)
received_size += len(data)
m.update(data)
f.write(data)
else:
print("文件接收完了哦,开心不?")
client_file_md5 = m.hexdigest()
f.close()
server_file_md5 = client.recv(1024)
print("服务器端的md5文件",server_file_md5)
print("客户端的md5文件", client_file_md5)
else:
print("诶呦喂,输入不合小的要求,请您以load为开始吧")
continue
client.close()
三、执行结果