在傳統(tǒng)的CS架構(gòu)的應(yīng)用中我們通??梢允褂胹ocket來(lái)進(jìn)行雙端的通信。但是使用socket只能和一個(gè)客戶端通信,python怎么實(shí)現(xiàn)并發(fā)的客戶端通信呢?又該如何進(jìn)行客戶端合法性驗(yàn)證呢?這些在CS架構(gòu)中的開發(fā)技術(shù)今天小編就分享給大家。
一、socketserver實(shí)現(xiàn)并發(fā)
tcp協(xié)議的socket是只能和一個(gè)客戶端通信的,使用socketserver可以實(shí)現(xiàn)和多個(gè)客戶端通信,他是在socket的基礎(chǔ)上進(jìn)行的封裝,底層還是調(diào)用的socket。
socket是底層模塊
socketserver是基于socket完成的
socketserver代碼格式:
服務(wù)端:
import socketserver # 引入模塊
import time
?
?
# 類名隨便定義,但是必須繼承socketserver.BaseRequestHandler此類。
class Myserver(socketserver.BaseRequestHandler):
?
def handle(self): # handle方法,固定名字
conn = self.request # conn相當(dāng)于每個(gè)客戶端連接過(guò)來(lái)的,客戶端信息
'''
以下就是基于conn客戶端信息,對(duì)每個(gè)客戶端鏈接到服務(wù)端必須做的操作
conn——>等于客戶端的連接信息
以此實(shí)現(xiàn)并發(fā)連接
'''
while True:
try:
content = conn.recv(1024).decode('utf-8')
conn.send(content.upper().encode('utf-8'))
time.sleep(1)
except ConnectionResetError:
break
?
?
# 對(duì) socketserver.ThreadingTCPServer 類實(shí)例化對(duì)象,將IP地址,端口號(hào),以及自己定義的類名傳入,并返回一個(gè)對(duì)象
server = socketserver.ThreadingTCPServer(('127.0.0.1', 4444), Myserver)
server.serve_forever() # 執(zhí)行對(duì)象server_forever方法,開啟服務(wù)端
客戶端:
import socket
?
sk = socket.socket()
sk.connect(('127.0.0.1', 4444))
?
while True:
sk.send(b'heelo')
content = sk.recv(1024).decode('utf-8')
print(content)
二、驗(yàn)證客戶端合法性
在分布式系統(tǒng)中實(shí)現(xiàn)一個(gè)簡(jiǎn)單的客戶端鏈接認(rèn)證功能,又不像SSL那么復(fù)雜,那么利用hmac+加鹽的方法實(shí)現(xiàn)。
思路:
服務(wù)端發(fā)送隨機(jī)字符串(并用客戶端和服務(wù)端都知道的秘鑰對(duì)隨機(jī)字符串進(jìn)行加密)——>客戶端接收到服務(wù)端發(fā)送的隨機(jī)字符串(并用相同的秘鑰進(jìn)行加密發(fā)送回服務(wù)端)——>服務(wù)端接收到客戶端發(fā)送的加密字符串和自己加密的字符串做對(duì)比(如果一致,就是合法客戶端,不一致,就立即關(guān)閉)
使用hashlib方法:
服務(wù)端
import socket
import hashlib
import os
?
# 設(shè)置雙方都擁有的秘鑰
secret = '秘鑰'.encode('utf-8')
?
sk = socket.socket()
sk.bind(('127.0.0.1', 4444))
?
sk.listen()
conn, _ = sk.accept()
?
# 給服務(wù)端發(fā)送32位隨機(jī)字節(jié)串
count = os.urandom(32)
conn.send(count)
?
# 并對(duì)字節(jié)串進(jìn)行加鹽加密
hs = hashlib.sha1(secret)
hs.update(count)
info_server = hs.hexdigest()
?
# 接收客戶端發(fā)送的對(duì)字節(jié)串加密后的信息
info_client = conn.recv(1024).decode('utf-8')
?
# 客戶端加密后的信息和服務(wù)端加密后的信息做對(duì)比
if info_server == info_client:
# 相等則連接合法,繼續(xù)操作
print('合法連接')
else:
# 不相等則斷開鏈接
print('非合法用戶')
conn.close()
客戶端
import socket
import hashlib
?
# 雙方共有的秘鑰
secret = '秘鑰'.encode('utf-8')
?
sk = socket.socket()
sk.connect(('127.0.0.1', 4444))
?
# 接收服務(wù)端發(fā)送的隨機(jī)字節(jié)
count = sk.recv(1024)
?
# 對(duì)隨機(jī)字節(jié)進(jìn)行加密
hs = hashlib.sha1(secret)
hs.update(count)
info = hs.hexdigest().encode('utf-8')
?
# 把加密后的字節(jié)發(fā)送回服務(wù)端做判斷
sk.send(info)
以上就是python怎么實(shí)現(xiàn)并發(fā)和客戶端合法性驗(yàn)證的詳細(xì)內(nèi)容,更多python生產(chǎn)開發(fā)技巧請(qǐng)關(guān)注W3Cschool后續(xù)相關(guān)文章!