2

服务器运行为nc -l 1234


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

客户端.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()

事件循环.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)服务器崩溃

localhost2)由于网线损坏,无法访问远程服务器(not )


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

4

1 回答 1

2

如何使 send() 调用不被阻止?

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

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

于 2020-03-17T18:24:30.540 回答