soketserver模块实现并发
Posted xiaoqianbook
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了soketserver模块实现并发相关的知识,希望对你有一定的参考价值。
soketserver模块
soketserver是在socket的基础上进行了一层封装,底层还是调用socket,soketserver可以同时实现多个客户端进行通信,多个人可以同时进行上传下载等.
socketserver客户端
# -*- coding:utf-8 -*- import socket client = socket.socket() client.connect((‘127.0.0.1‘,8001)) while 1: msg = input(‘客户端说>>>‘) client.send(msg.encode(‘utf-8‘)) from_sesrver_msg = client.recv(1024) print(from_sesrver_msg.decode(‘utf-8‘))
socketserver服务端
# -*- coding:utf-8 -*- #引入模块 import socketserver #自己写一个类,类名自己随便定义,然后继承 class Myserver(socketserver.BaseRequestHandler): def handle(self): #写一个handle方法,必须叫这个名字 while 1: from_client_msg = self.request.recv(1024) print(from_client_msg.decode("utf-8")) msg = input(‘服务端说:‘) self.request.send(msg.encode(‘utf-8‘)) if __name__ == ‘__main__‘: ip_port = (‘127.0.0.1‘,8001) server = socketserver.ThreadingTCPServer(ip_port,Myserver) #相当于进行bind,listen server.serve_forever() #使服务器一直开着
验证客户端的链接合法性
在客户端链接增加认证功能,利用hmac+盐的方式来实现
客户端
# -*- coding:utf-8 -*- from socket import * import hmac import os secret_key = b‘beijing huan ying ni!‘ def conn_auth(conn): """ 验证客户端到服务器的链接 :param conn: """ msg = conn.recv(32) h = hmac.new(secret_key,msg) digest = h.digest() conn.sendall(digest) def client_handler(ip_port,bufsize=1024): tcp_socket_client = socket(AF_INET,SOCK_STREAM) tcp_socket_client.connect(ip_port) conn_auth(tcp_socket_client) while 1: data = input(‘>>:‘).strip() if not data:continue if data == ‘quit‘:break tcp_socket_client.sendall(data.encode(‘utf-8‘)) respone = tcp_socket_client.recv(bufsize) print(respone.decode(‘utf-8‘)) tcp_socket_client.close() if __name__ == ‘__main__‘: ip_port = (‘127.0.0.1‘,9999) bufsize = 1024 client_handler(ip_port,bufsize)
服务端
# -*- coding:utf-8 -*- from socket import * import hmac import os secret_key = b‘beijing huan ying ni!‘ def conn_auth(conn): """ 认证客户端链接 :param conn: :return: """ print(‘开始验证新链接的合法性‘) msg = os.urandom(32) #生成一个32字节的随机字符串 conn.sendall(msg) h = hmac.new(secret_key,msg) digest = h.digest() respone = conn.recv(len(digest)) return hmac.compare_digest(respone,digest) def data_handler(conn,bufsize=1024): if not conn_auth(conn): print("该链接不合法,关闭") conn.close() return print("链接合法,开始通信") while 1: data = conn.recv(bufsize) if not data:break conn.sendall(data.upper()) def server_handler(ip_port,bufsize,backlog=5): """ 只处理链接 :param ip_port: :param bufsize: :param backlog: """ tcp_socket_server = socket(AF_INET,SOCK_STREAM) tcp_socket_server.bind(ip_port) tcp_socket_server.listen(backlog) while 1: conn,addr = tcp_socket_server.accept() print( "新链接[%s:%s]" %(addr[0],addr[1])) data_handler(conn,bufsize) if __name__ == ‘__main__‘: ip_port = (‘127.0.0.1‘,9999) bufsize = 1024 server_handler(ip_port,bufsize)
os.urandom(n)的使用方法
os.urandom(n)是一种bytes类型的随机生成n个字节字符串的方法,而且每次生成的值不相同.加上md5等加密处理,就能够成内容不同长度相同的字符串
import os from hashlib import md5 for i in range(10): print(md5(os.urandom(32)).hexdigest())
hmac模块
import hmac message = b‘Hello world‘ key = b‘secret‘ h = hmac.new(key,message,digestmod=‘MD5‘) print(h.hexdigest()) #比较两个密文是否相同,可以用hmac.compare_digest(密文,密文),返回True或False
hmac和普通hash算法非常相似,hmac输出的长度和原始hash算法长度一致,
注意: 传入的key和message都是bytes类型,str类型需要先编码为bytes
import hmac import random def hmac_md5(key,s): return hmac.new(key.encode(‘utf-8‘),s.encode(‘utf-8‘),‘MD5‘).hexdigest() class User(object): def __init__(self,username,password): self.username = username self.key = ‘‘.join([chr(random.randint(48,122)) for i in range(20)]) self.password = hmac_md5(self.key,password)
以上是关于soketserver模块实现并发的主要内容,如果未能解决你的问题,请参考以下文章