Page 2 of 2

Re: how can non-blocking socket instances be implemented

Posted: Tue Oct 23, 2018 6:05 am
by pythoncoder
To register a socket you need an event mask. Check the docs again ;)

Re: how can non-blocking socket instances be implemented

Posted: Sun Oct 09, 2022 5:44 am
by fishjoe
pythoncoder wrote:
Fri Jan 05, 2018 8:24 am
This example illustrates reading from, and writing to, a nonblocking socket.
this is what I assume a library of umqtt isn't it? It's so complicated that I cannot follow ...... :shock: :shock:

Re: how can non-blocking socket instances be implemented

Posted: Sun Oct 09, 2022 5:46 am
by fishjoe
can I only use select with stream? not DGRAM? what are the difference ?

many thanks.

Re: how can non-blocking socket instances be implemented

Posted: Mon Oct 10, 2022 12:13 pm
by DeaD_EyE
It also works with SOCK_DGRAM.

Here a testscript:

Code: Select all

import time
import uasyncio as asyncio
from uasyncio.stream import Stream

from socket import socket, AF_INET, SOCK_STREAM, SOCK_DGRAM, SOL_SOCKET, SO_REUSEADDR
from select import select


def with_select(ip="0.0.0.0", port=8080, stype=SOCK_DGRAM):
    interval = 1.0
    
    s = socket(AF_INET, stype)
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
    
    if stype is SOCK_STREAM:
        print("Connecting")
        s.connect((ip, port))
        addr = (ip, port)
    else:
        print("Opening port")
        s.bind((ip, port))
        
    s.setblocking(False)

    while True:
        recv_sockets, *_ = select([s], [], [], interval)
        
        for read in recv_sockets:
            if stype is SOCK_DGRAM:
                data, addr = read.recvfrom(1024)
            else:
                data = read.recv(1024)
            
            if not data or data.startswith(b"END"):
                read.close()
                return
                
            print(addr, data.decode().rstrip())
        
        print("Doing other stuff...")
        
    print("Done")
    s.setblocking(True)
    s.close()


async def _alive():
    while True:
        print("Alive")
        await asyncio.sleep(1)


async def with_async_stream(ip="0.0.0.0", port=8080, stype=SOCK_DGRAM):
    # to check if eventloop still works
    # and is not blocked by something
    asyncio.create_task(_alive())
    
    s = socket(AF_INET, stype)
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
    
    if stype is SOCK_STREAM:
        print("Connecting")
        s.connect((ip, port))
    else:
        print("Opening port")
        s.bind((ip, port))
        
    s.setblocking(False)
    stream = Stream(s)

    while True:
        # reading works
        data = await stream.read(1024)
        if not data or data.startswith(b"END"):
            break
        
        # await stream.awrite(data)
        #
        # this could not work, because UDP
        # is a connectionless protocol
        # the address is required, but Stream is not made
        # for UDP afik
        
        print(data.rstrip().decode())
        
    s.setblocking(True)
    s.close()


def run_with_async_stream():
    asyncio.run(with_async_stream(stype=SOCK_DGRAM))


with_select()

# does not work completly
# run_with_async_stream()

Opening port
Doing other stuff...
Doing other stuff...
Doing other stuff...
Doing other stuff...
('192.168.10.130', 37969) Test
Doing other stuff...
Doing other stuff...
Doing other stuff...

Re: how can non-blocking socket instances be implemented

Posted: Sat Nov 12, 2022 6:45 pm
by Ventran