【问题标题】:How to make send() call asynchronous?如何使 send() 调用异步?
【发布时间】:2020-03-17 18:11:48
【问题描述】:

服务器以nc -l 1234 运行


下面是使用事件循环的select() 调用在recv() 上未被阻止的客户端。

client.py

import socket
import sys
from eventloop import EventLoop

class Connection():
    def __init__(self):
        self.sock = socket.socket()
        self.sock.connect(('localhost', 1234))

    def fileno(self):
        return self.sock.fileno()

    def onRead(self):
        msg = self.sock.recv(1000).decode('utf-8')
        print(msg)

    def send(self, msg):
        self.sock.send(msg)

class Input():
    def __init__(self, sock):
        self.sock = sock

    def fileno(self):
        return sys.stdin.fileno()

    def onRead(self):
        msg = sys.stdin.readline().encode('utf-8')
        self.sock.send(msg)

sock = Connection()
inputReader = Input(sock)

eventLoop = EventLoop()
eventLoop.addReader(sock)
eventLoop.addReader(inputReader)
eventLoop.runForever()

eventloop.py

import select

class EventLoop():
    def __init__(self):
        self.readers = []

    def addReader(self, reader):
        self.readers.append(reader)

    def runForever(self):
        while True:
            readers, _, _ = select.select(self.readers, [], [])
            for reader in readers:
                reader.onRead()

但self.sock.send(msg) 呼叫可能会因不同原因被阻止:

1) 服务器崩溃

2) 无法访问远程服务器(不是localhost),原因是网线损坏


如何让send()通话不被阻塞?只需抛出消息并继续使用其余功能...不使用asyncio

【问题讨论】:

    标签: python sockets asynchronous sendasynchronousrequest


    【解决方案1】:

    如何让 send() 调用不被阻塞?

    通过使用非阻塞套接字,即self.sock.setblocking(0)。请注意,虽然发送可能会失败,但您必须抓住这一点。发送也可能不会发送所有给定的数据,但阻塞套接字也是如此,您只是忽略了这个问题。

    鉴于您目前对阻塞connect 没有任何问题,您应该仅在阻塞connect 之后将套接字设置为非阻塞。或者你必须处理实现一个更棘手的非阻塞连接。

    【讨论】:

    • 我需要在Connection 和Input 类中都设置这个吗?
    • @overexchange:您需要在套接字上仅设置一次,即在 Connection 或 Input 中,但不能同时在两者中设置。可能在connect 之后处于连接中。
    • 这会影响recv() 阻塞呼叫吗?由于select(),当前未被阻止
    • @overexchange: 是的,socket 上的每个操作都不会阻塞,但如果阻塞会导致错误。
    • @overexchange:设置套接字非阻塞会导致它在将数据放入完整的套接字缓冲区而不是阻塞时失败,直到套接字缓冲区中有空间。
    猜你喜欢
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 2012-04-05
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多