python-41-初识hmac与socketserver模块
Posted 广深-小龙 --扬帆起航!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python-41-初识hmac与socketserver模块相关的知识,希望对你有一定的参考价值。
前言
hmac:用来检验合法性,比如客户端后面发送一些请求,服务端要进行检验是否合法。
基本逻辑:客户端生成一串密文发送给客户端接收,后面客户端发送请求的时候要先校验是否与客户端密文一致
socketserver:是Python标准库中的一个高级模块,能实现多并发服务端。
一、hmac 模块
①服务端:
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()
合法与不合法打印结果:
二、socketserver 模块
①服务端:
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模块的主要内容,如果未能解决你的问题,请参考以下文章