zoukankan      html  css  js  c++  java
  • python 之 并发编程(非阻塞IO模型、I/O多路复用、socketserver的使用)

    9.16 非阻塞IO模型

    cpu占用率过高

    服务端:

    from socket import *
    import time
    s = socket()
    s.bind(('127.0.0.1',8080))
    s.listen(5)
    s.setblocking(False)    #使accept接收不到连接时不在阻塞
    ​
    r_list=[]
    while True:
        try:
            conn, addr = s.accept()
            r_list.append(conn)
        except BlockingIOError:
            # time.sleep(3)
            #print('可以去干其他的活了')
            #print('rlist: ',len(r_list))
            for conn in r_list:
                try:
                    data=conn.recv(1024)
                    conn.send(data.upper())
                except BlockingIOError:
                    continue

    客户端;

    from socket import *
    import os
    client = socket()
    client.connect(('127.0.0.1', 8080))
    ​
    while True:
        data='%s say hello' %os.getpid()
        client.send(data.encode('utf-8'))
        res=client.recv(1024)
        print(res.decode('utf-8'))

    9.17 I/O多路复用

    服务端:

    from socket import *
    import select
    s = socket()
    s.bind(('127.0.0.1',8080))
    s.listen(5)
    s.setblocking(False)                        #使accept接收不到连接时不在阻塞
    # print(s)
    ​
    r_list=[s,]
    w_list=[]
    w_data={}
    while True:
        print('被检测r_list: ',len(r_list))
        print('被检测w_list: ',len(w_list))      #rl中是r_list中建立连接的套接字对象
        rl,wl,xl=select.select(r_list,w_list,[],) #r_list=[server,conn]
        # print('rl: ',len(rl)) #rl=[conn,]
        # print('wl: ',len(wl))
    # 收消息
        for r in rl: #r=conn
            if r == s:
                conn,addr=r.accept()
                r_list.append(conn)
            else:
                try:
                    data=r.recv(1024)
                    if not data:
                        r.close()
                        r_list.remove(r)
                        continue
                    # r.send(data.upper())
                    w_list.append(r)
                    w_data[r]=data.upper()
                except ConnectionResetError:
                    r.close()
                    r_list.remove(r)
                    continue
        # 发消息
        for w in wl:
            w.send(w_data[w])
            w_list.remove(w)
            w_data.pop(w)
    View Code

    客户端:

    from socket import *
    import os
    client = socket()
    client.connect(('127.0.0.1', 8080))
    ​
    while True:
        data='%s say hello' %os.getpid()
        client.send(data.encode('utf-8'))
        res=client.recv(1024)
        print(res.decode('utf-8'))
    View Code

    9.18 socketserver的使用

    9.181 基于tcp的socketserver

    服务端:

    import socketserver
    # 通信循环
    class MytcpHandler(socketserver.BaseRequestHandler):
        def handle(self):
            while True:
                try:
                    data = self.request.recv(1024)  # 1024 接收数据的最大限制
                    if not data: break  # 针对linux系统
                    self.request.send(data.upper())  # 注意:收发都是以bytes为单位
                except ConnectionResetError:
                    break
            self.request.close()
    ​
    if __name__ == '__main__':
        #连接循环
        server=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MytcpHandler)
        server.serve_forever()
    ​
        print(server.server_address)
        print(server.RequestHandlerClass)
        print(server.socket)

    客户端:

    import socket
    client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(('127.0.0.1',8080))
    ​
    while True:
        msg=input('>>: ').strip()
        client.send(msg.encode('utf-8'))
        data=client.recv(1024)
        print(data.decode('utf-8'))
    client.close()

    9.182 基于udp的socketserver

    服务端:

    import socketserver
    # 通信循环
    class MyUDPHandler(socketserver.BaseRequestHandler):
        def handle(self):
            print(self.request)#(b'13404 hello', <socket.socket fd=460, family=AddressFamily.AF_INET, 
            res=self.request[0]#type=SocketKind.SOCK_DGRAM, proto=0, laddr=('127.0.0.1', 8080)>)
            print('客户端发来的数据:',res)
            
            self.request[1].sendto(res.upper(),self.client_address)
    ​
    if __name__ == '__main__':
        #连接循环
        server=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyUDPHandler)
        server.serve_forever()
    View Code

    客户端:

    import socket
    import os
    client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    ​
    while True:
        msg='%s hello' %os.getpid()
        client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
    ​
        res,server_addr=client.recvfrom(1024)
        print(res)
    View Code
  • 相关阅读:
    DHCP服务器搭建
    Nginx Web服务器
    ansible批量管理工具
    同网段存活IP公钥分发脚本
    inotify事件监控工具
    搭建云yum仓库和本地定时yum仓库
    NFS网络文件共享系统
    shell 脚本的讲解 与应用
    awk 命令精讲
    ACL权限控制 及特殊权限
  • 原文地址:https://www.cnblogs.com/mylu/p/11266748.html
Copyright © 2011-2022 走看看