How to make send() call asynchronous?

overexchange :

Server is running as nc -l 1234


Below is the client that is not blocked on recv() using event loop's select() call.

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()

But self.sock.send(msg) call can get blocked for different reasons:

1) server is crashed

2) Remote server(not localhost) is not reachable, due to broken network cable


How to make send() call not blocked? by just throwing the message and continue with rest of the functionality... without using asyncio

Steffen Ullrich :

How to make send() call not blocked?

By using a non-blocking socket, i.e. self.sock.setblocking(0). Be aware though that a send might fail then and you have to catch this. A send might also not send all given data, but this is also true with blocking sockets and you just ignored this problem.

Given that you currently have no problems with your blocking connect you should set the socket to non-blocking only after the blocking connect. Or you have to deal with implementing a non-blocking connect which is a bit more tricky.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=319763&siteId=1