第32篇 笔记-取消堵塞,验证client端的合法性,socketserver

内容回顾:
粘包现象:
TCP协议:
是一种流式传输,传输的是字节流,但是数据与数据之间是没有边界的,
流式传输:
不限定长度
传输方式可靠
传输速度慢
通信的过程中,连接conn会一直占用通讯资源
DUP协议:
面向数据包的传输
什么是数据包?
每次信息的发送,都是将: 自己的ip_port+对方的ip_port+message 以文件包的形式发送给对方
不能传输过长的数据
传输过程不可靠,数据会丢失
传输速度快
由于不需要建立连接,因此谁发过来的信息都能接收
内容大纲:
TCP协议中,server堵塞的取消
验证客户端的合法性
并发的socketserver
实现统一时刻server端可以和多个client客户端建立连接

TCP协议中,server堵塞的取消
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8989))
sk.setblocking(False)#取消堵塞
sk.listen()

while True:
    try:
        conn,addr = sk.accept()
    except BlockingIOError:
        conn.recv()

  



#为什么要验证客户端的合法性?
一些恶意的用户,如果知道server的ip地址,会采用扫端口的方法,端口0-65535,试出正确的端口,
从而与server端取得联系,接收server发来的信息,或者给server端发送病毒,攻击server端。
所以server在与client取得连接的时候需要验证客户端的合法性

验证客户端的过程?
server端 ---------------------随机的字符串---------------------->client端
根据相同的算法 根据特殊的算法,进行处理得到一个结果
的到一个结果与client端发送过的进行比较
如果验证通过,那么对方就是合法的客户端

server端:

import socket
import os
import hmac
secret_key = b'alex'
sk = socket.socket()
sk.bind(('127.0.0.1',8989))
sk.listen()
conn,addr = sk.accept()

def auth(conn):
    msg = os.urandom(32)#本身就是bytes类型的#生成一个随机的字符串
    conn.send(msg)#发送改字符串到客户端
    result = hmac.new(secret_key,msg)#secret_key加盐,处理这个字符串,得到一个结果
    client_digest = conn.recv(1024)#接收client发过来的结果
    if result.hexdigest() == client_digest.decode('utf-8'):#对比验证是否继续通讯
        print('合法的链接')
        return  True
    else:#不通过close
        print('不合法的链接')
        return  False
if auth(conn):
    print(conn.recv(1024))
    conn.close()
else:conn.close()
sk.close()

  



#client端:
import socket
import hmac
secret_key = b'alex'

sk = socket.socket()
sk.connect(('127.0.0.1',8989))
def auth(sk):
    msg = sk.recv(32)
    result = hmac.new(secret_key,msg)#<hmac.HMAC object at 0x0000003C1CFE7F98>
    print(result)
    res = result.hexdigest()#3f7f94cece407db2689b13c634467357
    print(res)
    sk.send(res.encode('utf-8'))

auth(sk)
sk.send(b'hello')
sk.close()

  



#socketserver这个模块超级有用,一定得记下来

socketserver是socket更上一级的模块,涵盖了socket的所有功能
socketserver建立在面向对象的编程


server基本框架:
import socketserver
#不需要再导入socket
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):
        conn = self.request#对于每个来访问的客户都是从这里建立连接
        pass#具体的收发内容
server = socketserver.ThreadingTCPServer(('127.0.0.1',9000),Myserver)
server.serve_forever()#建立多用户端的server

  



client端代码:
import socketserver
#不需要再导入socket
class Myserver(socketserver.BaseRequestHandler):
    def handle(self):#重写源码里面你的handle方法
        conn = self.request
        while True:
            conn.send(b'hello')
            print(conn.recv(1024))
server = socketserver.ThreadingTCPServer(('127.0.0.1',9000),Myserver)
server.serve_forever()#建立多用户端的server

  




client-taibai端:
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9000))

while True:
    print(sk.recv(1024))
    sk.send(b'taibai')

  



client-alex端:
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9000))

while True:
    print(sk.recv(1024))
    sk.send(b'alex')

  

猜你喜欢

转载自www.cnblogs.com/cavalier-chen/p/9664740.html
今日推荐