验证客户端的合法性、socketserver模块
一、为了防止客户端被人非法利用,需要在使用之前对客户端进行合法性验证。接下来就是客户端验证的几种方法
hmac 加密方法
import socket import os import hmac #能转化成密文模块 secret_key=b'apple' #密钥,必须是bytes类型 sk=socket.socket() sk.bind(('127.0.0.1',8008)) sk.listen() def check_con(con): #定义一个验证函数 msg=os.urandom(32) #系统模块中的urandom方法,可以生成指定位数的bytes数 con.send(msg) h=hmac.new(secret_key,msg) #new方法:接收两盒变量:密钥和要加密的变量 digest=h.digest() #密文变量等于 client_digest=con.recv(1024) #接收到的密文 return hmac.compare_digest(digest,client_digest)#hmac模块compare_digest方法:比较两个密文是否一致。 con,addr=sk.accept() res=check_con(con) if res: #比较 print('合法的客户端') con.close() else: print('不合法的客户端') con.close() sk.close()
#客户端 import socket import hmac secret_key=b'apple' #密钥:和服务端密钥要一致 sk=socket.socket() sk.connect(('127.0.0.1',8008)) msg=sk.recv(1024) h=hmac.new(secret_key,msg) #将接收到的信息进行加密 digest=h.digest() #得到密文变量 sk.send(digest) #将密文变量发送到服务端进行比较 sk.close()
客户端验证的总的思路是将服务端随机产生的指定位数的字节发送到客户端,两边同时用hmac进行加密,然后对生成的密文进行比较,相同就是合法的客户端,不相同就是不合法的端户端
二、socketserver模块:在socket模块的基础上加一层socket层,目的是让服务端可以处理多个线程,(能启动多个线程)。
服务端:
import socketserver class MyServer(socketserver.BaseRequestHandler): #必须要继承(socketserver.BaseRequestHandler类 def handle(self): # self.request 就相当于一个conn #必须要有def handle(self)方法 while True: print(self.client_address) msg = self.request.recv(1024).decode('utf-8') #相当于conn.recv if msg == 'q':break print(msg) info = input('%s>>>'%msg[:2]) self.request.send(info.encode('utf-8')) #相当于conn.recv方法 if __name__ == '__main__': server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyServer) # thread 线程 server.allow_reuse_address = True server.serve_forever()
注:self.request:相当于conn,addr=sk.accept()中的conn。。。。。。。
客户端:
#客户端 import socket sk = socket.socket() sk.connect(('127.0.0.1',8080)) while True: msg = input('>>>') if msg == 'q': sk.send(b'q') break sk.send(('美团 :'+msg).encode('utf-8')) ret = sk.recv(1024).decode('utf-8') print(ret) sk.close()
客户端没有socketclient,因为客户端不需要有多个客户端发过来的消息。客户端还是一样进行收发操作。