码迷,mamicode.com
首页 > 编程语言 > 详细

python-41-初识hmac与socketserver模块

时间:2020-03-26 21:27:43      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:ash   大于   str   逻辑   png   告诉   成功   add   handle   

前言

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=rbash教程.pdf
    FliePath=rC:\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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!