今天的主要内容为,文件上传的功能,与上传一致性(一致性校验),socketserve功能,以及看了一下socketserve源码
首先我们讲解一下文件上传的功能,
引入 import socket 模块以及ip 地址 到acpet都不写了
今天讲的稍稍复杂一点
因为要传送的时候,例如建立一个文件夹再传送,所以我们需要字典,里面加入一些例如名字,长度,操作方法
客户端传送的时候,要面对一个把字典转成字符的过程,这里引入 json模块
while 1:
cmd = input("enter a commend:") # put 111.png
action,filename = cmd.strip().split(" ")
filesize = os.path.getsize(filename) #获取文件的大小
#上传文件信息
file_info = {
"action":action,
"filename":filename,
"filesize":filesize
}
file_info_json = json.dumps(file_info) #把字典转成字符串
dic_len = len(file_info_json) #得到字典的长度
compress = struct.pack("i",dic_len) #压包
sk.send(compress) #第一次发送 把压缩包发送给服务器
file_info_json = json.dumps(file_info).encode("utf-8") #把字典转换成字符串形式, 再转换成字节形式
sk.send(file_info_json) #把序列化后的 字节形式的 字典发给服务器
#发送文件数据
with open(filename,"rb") as f:
for line in f:
sk.send(line) #rb 的模式读出来的 不用再编码了
print("上传成功")
服务端接收也是同理
while 1:
print("服务器准备连接")
conn,addr = sk.accept() #服务器不关
while 1:
header_pack = conn.recv(4) #接收压缩的报头
dic_len = struct.unpack("i",header_pack)[0] #得到的是一个元组,取出数值,得到字典的长度
# print(dic_len)
data = conn.recv(dic_len).decode("utf-8") #用得到的字典的字节长度值,接收下一次传来的序列化的字典
file_info = json.loads(data) #把接受到的字符串 转换成字典
print("file_info:",file_info) #得到字典
action = file_info.get("action")
filename = file_info.get("filename")
filesize = file_info.get("filesize")
#接收数据
with open("filename222pic.png","wb") as f: #要写出来文件格式
recv_data_length = 0
while recv_data_length < filesize:
data = conn.recv(1024) #字节串
recv_data_length += len(data)
f.write(data)
print("已经上传文件大小:",recv_data_length, "文件大小:",filesize)
print("上传成功")
上传一致性的校验:
每次上传或下载的时候,都加密一次这个文件 用for 循环每一行字节加密一行 然后在for 外面 写他的加密请看下一段代码,读取的时候同理
import hashlib
s='a'
a=hashlib.md5()
a.update(s.encode('utf8'))#在for里写这个 把变量全部叠加完
p=a.hexdigest() #在这里再统一打印一下该文件的密文,
print(p)
socketserve模块,目前来讲写这个固定格式吧, 以及后面看源码,目前自我感觉良好,只是老师讲的快?
import socketserver,struct,os
class myserver(socketserver.BaseRequestHandler):
def handle(self):
pass 不过以后需要注意的是 接收文件不再是 conn.recv 是self.request.recv()
传送文件也换成 self.request.recv()
server=socketserver.ThreadingTCPServer(('192.168.13.252',8899),myserver)
server.serve_forever()
这里除了 myserver是自己定义的变量,ip地址,端口自己写的,其他都固定的 且myserve自己写也没怎么,所以索性都倍吧