python3-socket验证客户端连接的合法性,下载进度条的实现

发布时间:2018-05-08 20:18:39编辑:Run阅读(5166)

    验证客户端链接的合法性

    如果你想在分布式系统中实现一个简单的客户端链接认证功能,又不像SSL那么复杂,那么利用md5+加盐或者hmac+加盐的方式来实现

    原理图

    blob.png


    为什么要随机字符串,是为了防止网络传输过程中,被截取。

    md5的实现方法

    server端代码

    import os
    import socket
    import hashlib
    
    sk = socket.socket()
    secret_key = '今晚打老虎'
    sk.bind(('127.0.0.1', 9595))
    sk.listen()
    
    while True:
        try:
            conn, addr = sk.accept()
            random_bytes = os.urandom(32)  # 随机返回一个长度为32位的bytes类型的组合
            conn.send(random_bytes)
            md5 = hashlib.md5(secret_key.encode('utf-8'))
            md5.update(random_bytes)
            ret = md5.hexdigest()
            msg = conn.recv(1024).decode('utf-8')
            if msg == ret:print('是合法的客户端')
            else:conn.close()
        finally:
            sk.close()
            break



    client端代码

    import socket
    import hashlib
    
    secret_key = '今晚打老虎'
    sk = socket.socket()
    sk.connect(('127.0.0.1', 9595))
    
    urandom = sk.recv(1024)
    md5_obj = hashlib.md5(secret_key.encode('utf-8'))
    md5_obj.update(urandom)
    sk.send(md5_obj.hexdigest().encode('utf-8'))
    print('---------')
    sk.close()

    先运行server,再运行client,执行结果为

    是合法的客户端



    hmac模块,专门用来做客户端合法性验证的(加密认证)

    server端代码

    import os
    import socket
    import hmac
    
    secret_key = '床前明月光'.encode('utf-8')
    sk = socket.socket()
    sk.bind(('127.0.0.1', 9595))
    sk.listen()
    
    while True:
        try:
            conn, addr = sk.accept()  # 建立连接
            random_bytes = os.urandom(32)  # 随机一个32长度的bytes类型组合
            conn.send(random_bytes)
            obj = hmac.new(key=secret_key, msg=random_bytes)
            ret = obj.hexdigest()
            msg = conn.recv(1024).decode('utf-8')
            if msg == ret:print('是合法的客户端')
            else:conn.close()
        finally:
            sk.close()
            break


    client端代码

    import socket
    import hmac
    
    secret_key = '床前明月光'.encode('utf-8')
    sk = socket.socket()
    sk.connect(('127.0.0.1', 9595))
    
    urandom = sk.recv(32)
    hmac_obj = hmac.new(key=secret_key, msg=urandom)
    sk.send(hmac_obj.hexdigest().encode('utf-8'))
    print('---------')
    sk.close()

    先运行server,再运行client,执行结果为

    是合法的客户端



    socketserver

    实现多个客户端,同时连接

    socketserver端代码

    import socketserver
    class MyServer(socketserver.BaseRequestHandler):
        def handle(self):
            while True:
                print(self.request)  # 这里不能使用input,否则卡住了
                self.request.send(b'hello')  # 跟所有的client打招呼
                print(self.request.recv(1024))  # 接收客户端的信息
    if __name__ == '__main__':
        socketserver.TCPServer.allow_reuse_address = True
        server = socketserver.ThreadingTCPServer(('127.0.0.1', 9000), MyServer)
        server.serve_forever()


    client端代码

    import socket
    sk = socket.socket()
    sk.connect(('127.0.0.1', 9000))
    
    while True:
        print(sk.recv(1024))
        inp = input('>>>').encode('utf-8')
        sk.send(inp)
    
    sk.close()

    先运行socketserver,在运行client,执行结果如下,发送一个消息,打印一次hello,可以同时开多个client执行

    download.gif



    模拟下载进度条:

    import sys
    import time
    def processBar(num, tital):
        rate = num / tital
        rate_num = int(rate*100)
        if rate_num == 100:
            r = '\r下载进度: {}%\n'.format(rate_num)
        else:
            r = '\r下载进度: {}%'.format(rate_num)
        sys.stdout.write(r)
        sys.stdout.flush
    
    for i in range(101):
        processBar(i, 100)  # 需要传入下载进度和文件总大小 
        time.sleep(0.1)  # 模拟下载延迟

    执行结果

    download.gif

关键字

上一篇: python3-socket黏包现象

下一篇: python3--进程