搜索
您的当前位置:首页正文

Socket Block Non-Block Python描述

来源:二三娱乐
image image
当我们建立了一个连接,可以不用等网页服务器的数据返回就可以接着做其它事情,当网页服务器准备好数据了,便会通知程序:数据准备好了,快来调用我吧。

下面我们来编写一个客户端服务器模型来理解以下阻塞以及非阻塞

server.py

import socket
import time

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 5000))
sock.listen(1)
while True:
    sc, sockname = sock.accept()
    print('I have accepted a connection from', sockname)
    print('Socket name: ', sc.getsockname())
    print('Socket peer: ', sc.getpeername())
    message = sc.recv(64)
    print('Recevied info is ', repr(message))
    time.sleep(3)//返回数据之前,先暂停3s
    sc.sendall(b'Response from server')
    sc.close()

block-client.py

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 5000))
sock.send(b'Resquest from client')
response = sock.recv(64)
sock.close()
print(response)
print('Test for blocking')//阻塞模式下,这条信息会在3s后才能输出

运行结果如下:


阻塞模式
from selectors import *
import socket

def connected(key, mask):
    selector.unregister(key.fd)
    sock.send(b'Resquest from client')
    selector.register(key.fd, EVENT_READ, read_response) #注册为一个读的event
    print('Test for non blocking')
    
def read_response(key, mask):
    global stopped
    response = sock.recv(64)
    print(response)
    selector.unregister(key.fd)
    stopped = True
    
selector = DefaultSelector()
stopped = False
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #注册为一个写的event
sock.setblocking(False)
try:
    sock.connect(('localhost', 5000))
except:
    pass
selector.register(sock.fileno(), EVENT_WRITE, connected)
while not stopped:
    events = selector.select()#选取已经准备好的event
    for event_key, event_mask in events:
        callback = event_key.data
        callback(event_key, event_mask) #回调函数

运行结果

非阻塞模式
在非阻塞模式中,把读和写注册为event,在它们未准备好之前,我们先可以执行其它的程序,在它们准备好之后,利用回调函数来进行程序的执行。
对于上面的程序我们可以这样来解释,当我们要在socket中写入数据时,把它注册为一个event,当写入的操作准备好时再写入,在写入操作未准备好时,我们可以执行其它的程序
我们可以把写入的操作定义为一个回调函数,当系统提醒我们说:文件准备好了,可以开始写了。我们就会调用回调函数connected

在写入操作完成后,我们就需要进行读取操作了,这时精彩的地方来了,程序会先输出Test for non blocking

为什么呢?
因为读取操作还没准备好,注意我们在server.py中写入了time.sleep(3),因此三秒之内读取操作是不会准备好的,这时就会执行其它程序,因此会先输出Test for non blocking

PS:
如果有什么错误或者疑问,可以在评论区指出


Top