1.介绍socket模块中一些其他常用方法
send和sendall的区别:
对于程序员来说,用起来是没有什么区别的.
实际上,在socket底层对于两个方法的封装有区别:
sendall(num)此方法会尝试一次性将num个数据发送出去
send(num)此方法会尝试先发送n个数据(n<num),接下来再尝试发送num-n个数据
(重点)setblocking(True) 阻塞
setblocking(False) 非阻塞
settimeout(int) 针对阻塞状态,设置一个延时等待
gettimeout() 获得延时的时间
2.关于客户端验证的事情 ---- 用到一个新的小模块hmac(内置) MD5算法
import hmac
a = b"aabbccdd" #盐
s = b"djfkdkd"
obj = hmac.new(a,s)
re = obj.digest() #bytes类型
print(re)
3.socketserver模块:现在没有学习并发编程,现在解决不了tcp协议中一个服务器同时连接多个客户端
import socketserver
class Myserver(socketserver.BaseRequestHandler):
def handle(self):
print(123)
self.request.send() #sk conn 等效于self.request
print(self.request.recv(1024).decode("utf-8"))
server = socketserver.TCPServer(("127.0.0.1",9090),Myserver)
server.serve_forever()
import os
print(os.urandom(长度)) #随机bytes类型
socket模块常用方法(客户端):
import socket
import time
sk = socket.socket()
sk.connect_ex(("127.0.0.1",9090))
time.sleep(2)
sk.send(b"dlkfdldf")
sk.close()
socket模块常用方法(服务器):
import socket
sk = socket.socket()
sk.setblocking(True) #设置阻塞 sk.setblocking(False)设置非阻塞,运行时会报错
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
#允许一个端口号重用的解决方法
sk.bind(("127.0.0.1",9090))
sk.listen()
while 1:
try:
conn,addr = sk.accept()
print(123)
conn.recv(1024)
print(123)
except BlockinglOError:
print(789)
conn.close()
sk.close()
socket模块常用方法(服务器):
import socket
sk = socket.socket()
sk.setblocking(True) #设置阻塞
sk.settimeout(5) #设置阻塞时间
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
#允许一个端口号重用的解决方法
sk.bind(("127.0.0.1",9090))
sk.listen()
print(123)
print(sk.gettimeout()) #获取阻塞时间
conn,addr = sk.accept()
print(456)
conn.close()
sk.close()
hmac 模块的应用( 客户端验证):
import socket
import hashlib
sk = socket.socket()
sk.connect((127.0.0.1",9090))
key = "天王盖地虎"
ch = sk.recv(1024)
md5_obj = hashlib.md5(key.encode("utf-8"))
md5_obj.update(ch)
re = md5_obj.hexdigest()
sk.send(re.encode("utf-8"))
sk.close()
hmac模块的应用(验证客户端)服务器:
import socket
import hashlib
sk = socket.socket()
sk.bind(("127.0.0.1",9090))
sk.listen()
conn,addr = sk.accept()
key = "天王盖地虎" #这个是固定盐
ch = "这是一个随机字符串"
conn.send(ch.encode("utf-8")) #把随机字符串发给client
md5_obj = hashlib.md5(key.encode("utf-8"))
md5_obj.update(ch.encode("utf-8")
re = md5_obj.hexdigest()
#固定的用盐的加密方式
client_re = conn.recv(1024).decode("utf-8")
#接收client端加密后的结果
if re == client_re:
print("连接成功")
else:
print("连接失败")
conn.close()
sk.close()
hmac模块的应用(验证客户端)服务器:
#引用import os模块中随机字符串方法
import socket
import os
import hashlib
sk = socket.socket()
sk.bind(("127.0.0.1",9090))
sk.listen()
conn,addr = sk.accept()
key = "天王盖地虎" #这个是固定盐
ch = os.urandom(20) #这个随机的bytes类型
conn.send(ch.encode("utf-8")) #把随机字符串发给client
md5_obj = hashlib.md5(key.encode("utf-8"))
md5_obj.update(ch)
re = md5_obj.hexdigest()
#固定的用盐的加密方式
client_re = conn.recv(1024).decode("utf-8")
#接收client端加密后的结果
if re == client_re:
print("连接成功")
else:
print("连接失败")
conn.close()
sk.close()
调用hmac模块中的加密方法(客户端):
#此代码用hmac模块实现机密:
import socket
import hmac
sk = socket.socet()
sk.connect(("127.0.0.1",9090))
key = "天王盖地虎"
ch = sk.recv(1024)
obj = hmac.new(key.encode("utf-8"))
re = obj.digest()
sk.send(re)
sk.close()
调用hmac模块中的加密方法(服务器):
import socket
import os
import hmac
sk = socket.socket()
sk.bind(("127.0.0.1",9090))
sk.listen()
conn,addr = sk.accept()
key = "天王盖地虎"
ch = os.urandom(20)
conn.send(ch) #把随机字符串发给client
obj= hmac.new(key.encode("utf-8"),ch)
re = obj.digest() #得到的是bytes类型
#固定的用盐的加密方式
client_re = conn.recv(1024) #接收client端加密后的结果
if re == client_re:
print("连接成功")
else:
print("连接失败")
conn.close()
sk.close()
回顾一下socketserver模块
import socketserver
class Myserver(socketserver.BaseRequestHandler):
def handle(self):
print(123)
self.request.send()
print(self.request.recv(1024).decode("utf-8")
server = socketserver.TCPServer(("127.0.0.1",9090)),Myserver)
server.serve_forever()
socketserver模块(客户端):
import socket
import json
sk = socket.socket()
sk.connect(("127.0.0.1",9090))
dic ={"username":None,"password":None}
while 1:
username = input("<<<")
password = input("<<<")
dic["username"] = username
dic["password"] = password
re = json.dumps(dic).encode("utf-8")
sk.send(re)
print(sk.recv(1024).decode("utf-8))
sk.close()
socketserver模块(服务器):
import socketserver
import json
import hashlib
class Myserver(socketserver.BaseRequestHandler):
def handle(self):
while 1:
dic_str =self.request.recv(1024).decode("utf-8")#接收序列化的字典
dic = json.loads(dic_str)#反序列化字典,字典中有用户名和密码
with open(文件名,encode= "utf-8")as f:
for i in f:
username , password = i.split(",")
if username == dic["username"]:
md5_obj = hashlib.md5(dic["username"].encode("utf-8"))
md5_obj.update(dic["password"].encode("utf-8"))
re = md5_obj.hexdigest()
if re == password.strip():
self.request.send(b"success")
else:
self.request.send(b"failed")
break
else:
self.request.send("用户不存在".encode("utf-8"))
server = socketserver.ThreadingTCPServer(("127.0.0.1",9090)),Myserver)#绑定一个服务
server.serve_forever()#永久性开启服务