标签:ash 大于 str 逻辑 png 告诉 成功 add handle
hmac:用来检验合法性,比如客户端后面发送一些请求,服务端要进行检验是否合法。
基本逻辑:客户端生成一串密文发送给客户端接收,后面客户端发送请求的时候要先校验是否与客户端密文一致
socketserver:是Python标准库中的一个高级模块,能实现多并发服务端。
①服务端:
import socket,os,hmac sk=socket.socket() sk.bind((‘127.0.0.1‘,9999)) sk.listen() conn,addr=sk.accept() def exp(): msg=os.urandom(32) # 随机生成字节 conn.send(msg) # 发送随机生成的字节 digest=hmac.new(msg).digest() # 生成密文给下面对比 res_digest=conn.recv(1024) # 接收客户端的密文 res=hmac.compare_digest(digest,res_digest) # 对比服务端与客户端的密文是否相等,返回bool return res res=exp() if res: print(‘合法请求‘) sk.close() else: print(‘不合法请求‘) sk.close()
②客户端:
import socket,hmac sk=socket.socket() sk.connect((‘127.0.0.1‘,9999)) msg=sk.recv(1024) h=hmac.new(msg) digest=h.digest() sk.send(digest) sk.close()
合法与不合法打印结果:
①服务端:
import socketserver class Mysevrer(socketserver.BaseRequestHandler): def handle(self): while 1: msg=self.request.recv(1024).decode(‘utf-8‘) if msg==‘8‘:break print(msg) info=input(‘info send:‘) self.request.send(info.encode(‘utf-8‘)) if __name__ == ‘__main__‘: server=socketserver.ThreadingTCPServer((‘127.0.0.1‘,9999),Mysevrer) server.serve_forever()
②客户端:
import socket sk=socket.socket() sk.connect((‘127.0.0.1‘,9999)) while 1: msg=input(‘send:‘) if msg==‘8‘:break sk.send(msg.encode(‘utf-8‘)) ret=sk.recv(1024).decode(‘utf-8‘) print(ret) sk.close()
基于前一篇:struct模块定制报头ftp实战,注释有解析。
基本逻辑:客户端获取文件大小,处理报头后告诉服务端,服务端每次接收一定字节数。
①服务端,接收:
def sevrer(sk,ip,port,buffer=10240): sk.bind((ip, port)) sk.listen() conn,addr=sk.accept() head_pack=conn.recv(4) # 先接收pack的4个字节 head_len=struct.unpack(‘i‘,head_pack)[0] # unpack解字节后得到一个元组,取第[0]个即可 head=conn.recv(head_len).decode(‘utf-8‘) # bytes报头内容 head_loads=json.loads(head) # json报头内容 FlieSize=head_loads[‘FlieSize‘] # 取json报头内容中FlieSize对应的值 with open(head_loads[‘FlieName‘],‘wb‘)as f: # 创建文件,名称=json报头内容中FlieName对应的名称 while FlieSize: # 如果FlieSize有数值 if FlieSize>=buffer: # 大于等于buffer,给下面直接写入buffer个字节 f.write(conn.recv(buffer)) # 写入buffer个字节 FlieSize-=buffer # FlieSize每次减少buffer个字节 else: # 如果小于buffer个字节,直接读完 f.write(conn.recv(buffer)) # 读取完毕,退出循环 break conn.close() sk.close() # 结束,关闭连接 if __name__ == ‘__main__‘: import socket, struct, json sk = socket.socket() sevrer(sk,ip=‘127.0.0.1‘,port=8888)
②客户端,上传:
def client(sk,FlieName,FliePath,buffer=10240): head={ ‘FlieName‘: FlieName, # 文件名 ‘FliePath‘: FliePath, # 文件目录 ‘FlieSize‘: None,} # 文件大小为空 cur_path=os.path.join(head[‘FliePath‘],head[‘FlieName‘]) # 拼接文件路径 FlieSize=os.path.getsize(cur_path) # 获取文件字节大小 head[‘FlieSize‘]=FlieSize # 将文件大小传入head字典 head_bytes=json.dumps(head).encode(‘utf-8‘) # 序列化 head_len=len(head_bytes) # 报头的长度 head_pack=struct.pack(‘i‘,head_len) # pack为4个字节长度 sk.send(head_pack) # 发送pack的4个字节 sk.send(head_bytes) # 发送bytes类型报头 with open(cur_path,‘rb‘)as f: # 打开拼接路径的文件 while FlieSize: # 如果FlieSize有数值 if FlieSize>=buffer: # 大于等于buffer,给下面直接写入buffer个字节 sk.send(f.read(buffer)) # 写入buffer个字节 FlieSize-=buffer # FlieSize每次减少buffer个字节 else: sk.send(f.read(buffer)) # 如果小于buffer个字节,直接读完 break # 读取完毕,退出循环 sk.close() # 关闭连接 return FlieSize if __name__ == ‘__main__‘: import socket, struct, os, json sk = socket.socket() sk.connect((‘127.0.0.1‘,8888)) FlieName=r‘bash教程.pdf‘ FliePath=r‘C:\Users\Administrator\Desktop‘ print(‘上传成功,总共字节:‘,client(sk,FlieName,FliePath))
欢迎来大家QQ交流群一起学习:482713805
python-41-初识hmac与socketserver模块
标签:ash 大于 str 逻辑 png 告诉 成功 add handle
原文地址:https://www.cnblogs.com/gsxl/p/12577021.html