33 socketserver 进度条 验证身份 用户的三次登录验证
主要内容:
1 . socketserver 模块 :
a : 是出于socket抽象层与应用层之间的一层, 比socket更贴近用户.
b : 主要解决问题 : tcp协议中, 服务器不能同时连接多个客户端的问题
服务器端:
import socketserver class Mysocket(socketserver.BaseRequestHandler): def handle(self): msg_c = self.request.recv(1024).decode('utf-8') print(msg_c) self.request.send(msg_c.upper().encode('utf-8')) socket = socketserver.TCPServer(('127.0.0.1',8090), Mysocket) socket.serve_forever() #开启一个永久性的服务
客户端:
import socket sk = socket.socket() sk.connect(('127.0.0.1',8090)) while 1: msg_s = input('请输入一个英文单词>>>:') sk.send(msg_s.encode('utf-8')) print(sk.recv(1024).decode('utf-8')) sk.close()
注意 :也存在一个问题 : 虽然服务器可以同时接收多个客户端发消息,但是,只能等到第一个客户端发送完了,第二个客户端再发才能接收到消息, 不能同时与多个客户端发消息.
2 . 验证身份
版本一 :
服务器端代码:
import socket import hashlib sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() conn, addr = sk.accept() s = '随意的一个字符串' sor = 'alex' conn.send(s.encode('utf-8')) md5_obj = hashlib.md5(sor.encode('utf-8')) md5_obj.update(s.encode('utf-8')) result = md5_obj.hexdigest() md5_mi = conn.recv(1024).decode('utf-8') if result == md5_mi: conn.send('验证成功'.encode('utf-8')) else: conn.send('验证失败'.encode('utf-8')) conn.close() sk.close()
客户端代码:
import socket import hashlib sk = socket.socket() sk.connect(('127.0.0.1',8080)) sor = 'alex' s = sk.recv(1024) md5_obj = hashlib.md5(sor.encode('utf-8')) md5_obj.update(s) result = md5_obj.hexdigest() sk.send(result.encode('utf-8')) print(sk.recv(1024).decode('utf-8')) sk.close()
版本二: 版本一的优化
服务器端的代码:
import socket
import hashlib
import hmac
import os
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
conn, addr = sk.accept()
s = os.urandom(16) #随机出一个num位的随机bytes
sor = 'alex'
conn.send(s)
md5_obj = hmac.new(sor.encode('utf-8'), s)
result = md5_obj.digest()
md5_mi = conn.recv(1024)
if result == md5_mi:
conn.send('验证成功'.encode('utf-8'))
else:
conn.send('验证失败'.encode('utf-8'))
conn.close()
sk.close()
客户端的代码:
import socket
import hashlib
import hmac
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
sor = 'alex'
s = sk.recv(1024)
# 引入hmac,简化代码, 结果直接是bytes
md5_obj = hmac.new(sor.encode('utf-8'), s)
result = md5_obj.digest()
sk.send(result)
print(sk.recv(1024).decode('utf-8'))
sk.close()
3 . 用户的三次登录验证
服务器端代码:
import socketserver import json import hashlib class Mysocket(socketserver.BaseRequestHandler): def handle(self): sor = b'thin' while 1: str_dic = self.request.recv(1024).decode('utf-8') if not str_dic: break dic = json.loads(str_dic) if not dic['status']: '''未登录成功''' with open('userinfo', 'r', encoding='utf-8') as f : for line in f: user, pwd = line.strip().split('|') if user == dic['username']: md5_obj = hashlib.md5(sor) md5_obj.update(dic['password'].encode('utf-8')) result = md5_obj.hexdigest() if pwd == result: dic['status'] = True else: dic['reason'] = '密码错误' break else: '''用户不存在''' dic['reason'] = '用户不存在' str_dic = json.dumps(dic) self.request.send(str_dic.encode('utf-8')) else: # self.request.send('登录成功'.encode()) pass socket = socketserver.TCPServer(('127.0.0.1', 8888), Mysocket) socket.serve_forever()
客户端代码:
import socket import hashlib import json sk = socket.socket() sk.connect(('127.0.0.1', 8888)) dic = {'status': False, 'username': None, 'password':None} c = 3 while c: username = input('请输入用户名>>>: ') password = input('请输入密码>>>:') md5_obj = hashlib.md5(password.encode('utf-8')) md5_obj.update(username.encode('utf-8')) mi_md5 = md5_obj.hexdigest() dic['username'] = username dic['password'] = mi_md5 str_dic = json.dumps(dic) sk.send(str_dic.encode('utf-8')) # 服务器应该回复我一个这样的字典: # 是否登录成功,如果没有登录成功是因为什么原因? res_str = sk.recv(1024).decode('utf-8') result = json.loads(res_str) if result['status'] == True: print('登录成功') break else: print('失败 %s' % result['reason']) c = c - 1 sk.close()
4 . 进度条
import time for i in range(51): time.sleep(0.12) print('\r' + i*'=' + '>' +str(i * 2) + '%', end='')
输出带颜色的进度条:
import time for i in range(51): time.sleep(0.12) print('\r' +'\033[35m '+ i*'=' + '>' +str(i * 2) + '%'+'\033[0m', end='') # 输出带颜色的进度条.