如何使 send() 调用异步?
How to make send() call asynchronous?
服务器 运行 为 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
How to make send() call not blocked?
通过使用非阻塞套接字,即 self.sock.setblocking(0)
。请注意,发送可能会失败,您必须抓住这一点。发送也可能不会发送所有给定数据,但对于阻塞套接字也是如此,您只是忽略了这个问题。
鉴于您目前的阻塞 connect
没有问题,您应该仅在阻塞 connect
之后将套接字设置为非阻塞。或者你必须处理实现一个有点棘手的非阻塞连接。
服务器 运行 为 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
How to make send() call not blocked?
通过使用非阻塞套接字,即 self.sock.setblocking(0)
。请注意,发送可能会失败,您必须抓住这一点。发送也可能不会发送所有给定数据,但对于阻塞套接字也是如此,您只是忽略了这个问题。
鉴于您目前的阻塞 connect
没有问题,您应该仅在阻塞 connect
之后将套接字设置为非阻塞。或者你必须处理实现一个有点棘手的非阻塞连接。