网络编程 02:非阻塞套接字与IO多路复用

一.数据流

是一组有序,有起点和终点的字节的数据序列。是只能被读取一次或少数几次的点的有序序列。其包括输入流和输出流。

1.输入流

只能读不能写,从键盘中获取文件

2.输出流

只能写不能读,像显示器,打印机或文件中传输数据

二.IO( I:input(输入),O:output(输出))

1.解释

(1)I/O操作

在信息的交换过程中,对这些流进行数据的收发操作,例如:输入与输出。

2.交互

三.基本IO模型

1.分类

(1)阻塞IO

只会专门等待一件事物完成后才会进行下一项任务。(例如:专门等鱼上钩,等的时候不做其他事情,鱼上钩才会结束等的动作,做其他事情,开始烧水)

优点:进程阻塞挂起,不消耗CPU资源,能够及时响应每个操作且难度较低

缺点:进程阻塞的时候不能进行其他操作,不适合并发量大的应用开发

import socket

# 得到服务端套接字
server = socket.socket()
# 绑定IP和端口
server.bind(('127.0.0.1',9090))
# 最大监听数
server.listen(10)

all_conn = []
for i in range(2):
    # conn,对等连接套接字,addr 客户端信息
    conn,addr = server.accept()
    all_conn.append(conn)

for conn in all_conn:
    data = conn.recv(1024)
    if data:
        print(data)
    else:
        conn.close()
        all_conn.remove(conn)

server.close()
import socket

client = socket.socket()

client.connect(('127.0.0.1',9090))

client.send(b'ok')

client.close()

(2)非阻塞IO

在进行一个任务的时候,可以做别的事,但必须每隔一段时间就查看任务的进程。(例如:不需要把时间都花费在钓鱼上,等到鱼上钩的时候做其他事情,烧水,每隔一段时间回来看下鱼上钩没有,把鱼掉上来,轮询。)

优点:在线程等待的时候去做其他任务,效率高

缺点:消耗大,而轮询对于CPU来说有较大的浪费,消耗。延迟,每隔一段时间才去轮询一次操作,而任务可能就在中间任意时间完成,数据响应不及时。

服务端:

import socket
from time import sleep
# 得到服务端套接字
server = socket.socket()
#设置为非阻塞套接字,需要在其他操作之前设置
server.setblocking(False)
# 绑定IP和端口
server.bind(('127.0.0.1',2020))
# 最大监听数
server.listen(10)

all_conn = []
while True:
    try:
        conn,addr = server.accept()
        conn.setblocking(False)
        all_conn.append(conn)
    except BlockingIOError:
        pass
    except Exception as e:
        print(f'发生异常{e}')

    for conn in all_conn:
        try:
            data = conn.recv(1024)
            if data:
                print(data)
                conn.send(data)
            else:
                conn.close()
                all_conn.remove(conn)
        except BlockingIOError:
            pass
        except Exception as e:
            print(f'发生异常{e}')

客户端:

import socket
from time import sleep  #导入休眠模块

client = socket.socket()

client.connect(('127.0.0.1',9090))

for i in range(100):
    client.send(b'liangge')
    data = client.recv(1024)
    print(data)
    sleep(1)

client.close()

(3)IO多路复用(事件驱动IO)

利用一个任务去查看另一个任务的进展(例如:雇佣一个人专门看鱼有没有上钩,不断轮询看这个鱼竿,如果有鱼上钩就通知把鱼钓上来,烧水。)

优点:占用资源少,消耗cpu少

缺点:需要两个系统调用

原理:select/epoll 这个 function 会不断的轮询所负责的 socket ,当某个 socket 有数据到达了,就通过用户

epoll是最佳打工仔,是 Linux 最好的 IO 多路复用器,且只有 linux 有。epoll 是一个惰性事件回调,用户自己去调用回调过程,操作系统进行通知

服务端:

import socket
import selectors  # IO多路复用选择器模块

epoll_select = selectors.EpollSelector() # 实例化
# selectors.EpollSelector()  # 默认选择器,自动根据不同的操作系统进行自动选择

server = socket.socket()
server.bind(('127.0.0.1',9090))
server.listen(10)

def f_recv(conn):
    data = conn.recv(1024)
    if data:
        print(data)
        conn.send(data)
    else:
        conn.close()

def f_accept(server):
    conn,addr = server.accept()
    epoll_select.register(conn, selectors.EVENT_READ,f_recv)

# selectors.EVENT_READ 有事件发生的时候,调用回调函数,第三个参数
epoll_select.register(server,selectors.EVENT_READ,f_accept)

while True:
    events = epoll_select.select() # 查询
    for key,mask in events:
        func = key.data  # 函数体
        conn = key.fileobj  # 已经注册的套接字
        func(conn)  # f_accept(conn)
    print(events)

客户端:

import socket
from time import sleep  #导入休眠模块

client = socket.socket()

client.connect(('127.0.0.1',9090))

for i in range(100):
    client.send(b'liangge')
    data = client.recv(1024)
    print(data)
    sleep(1)

client.close()

四.并发与并行

1.并发

同一时间段发生多件事情

同一时刻只能有一条指令执行,但是快速的切换执行,宏观看起来就是一起执行,但微观并不是同时执行的。

2.并行

同一时间点发生多件事情

无论从微观上来说还是宏观都是一起执行的(而目前 python 只能实现并发,向并行靠拢)

附(今日份学习):

阻塞IO:
在这里插入图片描述
非阻塞 IO
在这里插入图片描述
在这里插入图片描述
IO 多路复用
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南风和云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值