zoukankan      html  css  js  c++  java
  • Python学习笔记-Day32-socketserver模块实现TCP协议的server与多个client端连接

    内容大纲:

    一、socket()里的四个参数

    二、socket模块里的其他方法

    三、客户端合法性验证

    四、socketserver模块

    一、socket()里的四个参数

    sk = socket(family = AF_INET,type = SOCK_STREAM,proto = 0,fileno = None)

    二、socket模块的其他方法

    1、服务端套接字函数

    s.bind():绑定(主机,端口号)到套接字

    s.listen():开始TCP监听

    s.accept():被动接受TCP客户的连接,(阻塞式)等待连接的到来

    2、客户端套接字函数

    s.connect():主动初始化TCP服务器连接

    s.connect_ex():connect()函数的扩展版本,出错时返回错误码,而不是抛出异常

    3、公共用途的套接字函数

    s.recv():接收TCP数据

    s.send():发送TCP数据,返回发送的字节大小,执行一次这个函数时,并不一定能发送完给定的数据,可能需要重复多次才能发送完成

    s.sendall():发送完整的TCP数据,成功返回None,失败则抛出异常

    s.recvfrom():接收UDP数据

    s.sendto():发送UDP数据

    s.getpeername():连接到当前套接字的远端的地址

    s.getsockname():当前套接字的地址

    s.getsockopt():返回指定套接字的参数

    s.setsockopt():设置指定套接字的参数,遇到Error:Address already in use时在前面加上s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

    s.close():关闭套接字

    4、面向锁的套接字方法

    s.setblocking():设置套接字的阻塞与非阻塞模式

      阻塞:正在运行的进程提出系统服务请求,但是因为某种原因未得到操作系统的立即相应,该进程只能调用阻塞原语把自己阻塞住,等待相应的事件出现后才被唤醒

    s.settimeout():设置阻塞套接字操作的超时时间

    s.gettimeout():得到阻塞套接字的超时时间

    5、面向文件的套接字函数

    s.fileno():套接字的文字描述符

    s.makefile():创建一个与该套接字相关的文件

     三、验证客户端的合法性

    背景:当使用TCP协议进行通信且不需要登录验证的时候,会有非法客户进行访问,这时可以设置客户端的合法性验证

    步骤:

    ① server端使用os模块的urandom(n),生成一个n位的bytes类型的随机字符串

    ② 将该随机字符串发送给client

    ③ client接收随机字符串并对该字符串进行加盐的摘要,得到一个结果发送给server

    ④ server对随机字符用同样的盐进行摘要,并和client发送的结果进行比较

    ⑤ 如果结果相同就可以继续访问,结果不同就关闭conn

    import os
    import hmac
    import socket
    
    key = b'hello'  #
    def auth(conn):
        msg = os.urandom(32)  # 随机生成一个32位的bytes类型的字符串
        conn.send(msg)  # 将随机字符串发送给client
        dig = hmac.new(key,msg)  # server对随机字符串进行摘要,得到一个对象,需要用hexdigest()才能取值
        result = conn.recv(1024) # 收到客户端的验证结果
        if dig.hexdigest()== result.decode('utf-8'):
            print('合法')
            return True
        else:
            print('不合法')
            return False
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',9005))
    sk.listen()
    conn,addr = sk.accept()
    if auth(conn):
        msg = conn.recv(1024)
        print(msg.decode('utf-8'))
    else:
        conn.close()

    client端:

    import hmac
    import socket
    
    key = b'hello'
    def auth(sk):
        msg = sk.recv(32) # 接收server发送的随机字符串
        result = hmac.new(key,msg)  
        sk.send(result.hexdigest().encode('utf-8'))
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',9005))
    auth(sk)
    sk.send(b'welcome')
    sk.close()

    四、socketserver模块:实现TCP协议的多客户端访问

    server端:

    import  socketserver
    # 用类的方式实现
    class Myserver(socketserver.BaseRequestHandler):# 必须继承socketserver.BaseRequesthandler
        def handle(self):  # 必须实现handle方法
            conn = self.request
            print(conn)  # 这里的conn就是socket里的conn
            msg = conn.recv(1024)
            print(msg.decode('utf-8'))
            conn.close()
    server = socketserver.ThreadingTCPServer(('127.0.0.1',9002),Myserver)  # 实例化
    server.serve_forever()    # Handle one request at a time until shutdown.

    client端:

    # 与socket模块相同
    import socket
    sk = socket.socket()
    sk.connect(('127.0.0.1',9002))
    sk.send(b'hello')
    sk.close()
  • 相关阅读:
    JavaFx初探
    TraceView总结
    sprintf,你知道多少?
    C/C++:多个.cpp文件包括同一个.h头文件定义方法
    Android中Preference的使用以及监听事件分析
    Android系统默认Home应用程序(Launcher)的启动过程源码分析
    升级、备份红帽PaaS openshift 上的 wordpress
    几种开源分词工具的比較
    设计模式奠基石——UML关系转化为代码
    Windows 7系统安装MySQL5.5.21图解
  • 原文地址:https://www.cnblogs.com/tian-tian/p/9663522.html
Copyright © 2011-2022 走看看