Due to high demand expect some shipping delays at this time, orders may not ship for 1-2 business days.
0

uPy socket vs cPy socket need help
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

uPy socket vs cPy socket need help

by johncblacker on Fri Mar 12, 2021 11:11 am

I have this code that runs on uPy:
if not self._started :
self._server = socket.socket()
self._server.setsockopt( socket.SOL_SOCKET,
socket.SO_REUSEADDR,
1 )
self._server.bind(self._srvAddr)
self._server.listen(16)

I want to convert it to equivalent cPy code; but I just can't wrap my brain around the implementation of the "socketpool" concept in cPy and need help. I can find examples of receiving data from a remote website, but in my case, I'm trying to convert some uPy webserver code to cPy. Here's what I tried in cPy:
print("Server starting")
if not self._started :
self._server = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(socket, ssl.create_default_context())
print("Requests: ", requests)
#self._server.setsockopt( socket.SOL_SOCKET,
# socket.SO_REUSEADDR,
# 1 )
#self._server.bind(self._srvAddr)
#self._server.listen(16)
When I run this I get connection refused on my browser. I need a quick, short example of reading and writing via sockets with cPy.

johncblacker
 
Posts: 163
Joined: Mon Aug 27, 2018 1:45 pm

Re: uPy socket vs cPy socket need help

by johncblacker on Fri Mar 12, 2021 1:05 pm

I've recently tried to add:
srvsock = self._server.socket(socketpool.SocketPool.AF_INET, socketpool.SocketPool.SOCK_RAW)
print("srvsock = ", srvsock)
srvsock.listen(16)

But, I get an "AttributeError: 'Socket' object has no attribute 'listen'"
which when I issue:
>>> dir(socketpool.Socket)
['__class__', '__del__', '__enter__', '__exit__', '__name__', 'close', 'connect', 'recv_into', 'recvfrom_into', 'send', 'sendto', 'settimeout']
But, this doesn't match the doc which indicates there is a "bind" and "listen" available? Now I'm really confused...what happened to these two items?

johncblacker
 
Posts: 163
Joined: Mon Aug 27, 2018 1:45 pm

Re: uPy socket vs cPy socket need help

by tannewt on Fri Mar 12, 2021 4:20 pm

The SocketPool object should be used in place of the `socket` module.

What version of CircuitPython are you running? bind and listen were added relatively recently I believe.

tannewt
 
Posts: 2396
Joined: Thu Oct 06, 2016 8:48 pm

Re: uPy socket vs cPy socket need help

by johncblacker on Fri Mar 12, 2021 4:26 pm

Here's what I'm running:
sysname='esp32s2', nodename='esp32s2', release='6.1.0', version='6.1.0 on 2021-01-21', machine='FeatherS2 with ESP32S2'
I did a dir(socketpool.SocketPool) and don't see a bind or listen there either.

johncblacker
 
Posts: 163
Joined: Mon Aug 27, 2018 1:45 pm

Re: uPy socket vs cPy socket need help

by johncblacker on Fri Mar 12, 2021 4:32 pm

I changed to this:
self._server.listen(16)
and got this:
AttributeError: 'SocketPool' object has no attribute 'listen'
So, I must be doing something wrong...

johncblacker
 
Posts: 163
Joined: Mon Aug 27, 2018 1:45 pm

Re: uPy socket vs cPy socket need help

by tannewt on Fri Mar 12, 2021 4:34 pm

Use the latest beta or even "absolute newest". There have been many improvements since 6.1.0.

tannewt
 
Posts: 2396
Joined: Thu Oct 06, 2016 8:48 pm

Re: uPy socket vs cPy socket need help

by johncblacker on Fri Mar 12, 2021 4:46 pm

OK, was trying to do a build of the absolute latest repo, but kept getting errors...will just download the latest instead.
Thanks.

johncblacker
 
Posts: 163
Joined: Mon Aug 27, 2018 1:45 pm

Re: uPy socket vs cPy socket need help

by johncblacker on Fri Mar 12, 2021 6:08 pm

OK, getting further, I think. Here's my code so far:
self.srvsock = self._server.socket(socketpool.SocketPool.AF_INET, socketpool.SocketPool.SOCK_RAW)
print("srvsock = ", self.srvsock)
#print("socket info: ", self.srvsock.getaddrinfo())
#requests = adafruit_requests.Session(self._server.socket, ssl.create_default_context())
#print("Requests: ", requests.Session)
#self._server.setsockopt( socket.SOL_SOCKET,
# socket.SO_REUSEADDR,
# 1 )
#srvsock.bind(self._srvAddr)
self.srvsock.bind(self._srvAddr ) # hard coded srvAddr to 192.168.0.5 for now
self.srvsock.listen(16)

Next over to this function:
def _serverProcess(self) :
self._started = True
while True :
try :
client, cliAddr = self.srvsock.accept()
print("Client: %s, %s", client, cliAddr)
except Exception as ex :
print("Exception Client: ", ex)
if ex.args and ex.args[0] == 113 :
print(ex.args, ex.args[0])
break
continue
self._client(self, client, cliAddr)
self._started = False
However, now I'm just sitting there and when I connect from my browser, I still get:
192.168.0.5 refused to connect.
Search Bing for 192 168 0 5
ERR_CONNECTION_REFUSED

I am connecting to the correct board address,

johncblacker
 
Posts: 163
Joined: Mon Aug 27, 2018 1:45 pm

Re: uPy socket vs cPy socket need help

by FriehoffT on Sun Mar 14, 2021 1:27 pm

Here a modification to your code that starts working for me...

Code: Select all | TOGGLE FULL SIZE
MYIP = str(wifi.radio.ipv4_address)
spool = socketpool.SocketPool(wifi.radio)
srvsock = spool.socket(spool.AF_INET, spool.SOCK_STREAM)
print("mysock type:", type(srvsock), srvsock)

srvsock.bind((MYIP, 80))
srvsock.listen(16)
srvsock.setblocking(False)
srvsock.settimeout(0)


The main loop:

Code: Select all | TOGGLE FULL SIZE

sockets = []
loopcount = 0
acttime = time.monotonic()
oncepersecond = acttime
while True:
    acttime = time.monotonic()
    loopcount += 1
    while True:  # dummy loop for exit in the middle
        try:
            client_socket, cliAddr = srvsock.accept()
            print(f"Client: {client_socket}, {cliAddr[0]}, {cliAddr[1]}")
            from_client, msg = receive_message(client_socket)
            if msg is False:
                print("no Message!")
                break
            print("Message:\r\n", msg)
            string_to_send = "Hello! " + str(time.monotonic()) + " \r\n"
            bytes_to_send = string_to_send.encode("UTF-8")
            bytes_send = client_socket.send(bytes_to_send)
            print("sentto result:", bytes_send, bytes_to_send, )
            sockets.append(from_client)
        except OSError as e:
            if e.errno == 11:
                break
            print("Exception:", type(e), str(e), dir(e))
        except Exception as e:
            sys.print_exception(e)
            print(dir(e))
        break  # the dummyloop allways at the end
    if acttime - oncepersecond > 1:
        oncepersecond = acttime
        print("once per second!")


And my receive_message function:

Code: Select all | TOGGLE FULL SIZE

def receive_message(client_socket):
    try:
        packet = bytearray(1024)
        result = client_socket.recvfrom_into(packet)
        received_bytes = result[0]
        print(f" received {received_bytes}")
        return result[1], packet[:received_bytes].decode("UTF-8")

    except Exception as e:
        print("exception :", str(e))
        return False, False



With this code, I can already see the "Hello message" in the browser sometimes.
Maybe I need to send "better" HTML.

FriehoffT
 
Posts: 33
Joined: Wed Sep 11, 2019 7:30 am

Re: uPy socket vs cPy socket need help

by FriehoffT on Mon Mar 15, 2021 10:44 am

With 6.2.0-beta.2 and 6.2.0-beta.3 the sockets are working unreliable.
Sending (even relatively small buffers) sometimes does not send the whole buffer and other times the error EAgain is raised repeatedly.
However most of the time with the handling this situation the complete website can be transferred to the browser,
More seriously is the fact that receiving data stops working after some time. In these cases, read buffer length of 0 bytes are reported.
In these cases only restarting the CP app helps.
In the Chrome debug console one can see that the website tries to send get-requests but are these are failing / timing out.

No chance to work/debug further on that with the current CP versions.

Note: If I leave my MagTag running while Chrome sends get requests CP on MagTag resets or crashes. (The com port disappears and the drive is unmounted)

Thomas

PS: I tried to port a similar code from an ESP32 running MicroPython (which I did for a project in March 2018).
This code usually runs fine for months without any "hiccups"!
Having async await, asyncio.get_event_loop(), loop.run_forever() and threads available in MicroPython makes things so much easier to code as with the single worker thread in CircutiPython !
Question: Any plans for also forking MicroPythons async / threading model for CircuitPython?

FriehoffT
 
Posts: 33
Joined: Wed Sep 11, 2019 7:30 am

Re: uPy socket vs cPy socket need help

by danhalbert on Mon Mar 15, 2021 10:53 am

@FriehoffT Could you open a new thread, or perhaps better, open an issue via https://github.com/adafruit/circuitpyth ... new/choose ?

Were these things working better before beta.2? We would be interested in the simplest version of your source code that has issues.

Are you using I2C? We have recently made a change that seems to fix some bad interactions between I2C and wifi.

danhalbert
 
Posts: 2380
Joined: Tue Aug 08, 2017 12:37 pm

Re: uPy socket vs cPy socket need help

by FriehoffT on Mon Mar 15, 2021 11:31 am

Sure I can open an issue at GITHUB.
And no, in this example I am not using and I2C.
I just wanted to get a minimalistic webserver running.

FriehoffT
 
Posts: 33
Joined: Wed Sep 11, 2019 7:30 am

Re: uPy socket vs cPy socket need help

by johncblacker on Tue Mar 16, 2021 11:22 am

Doesn't matter to me anymore, I returned the feather-s2 board. I just don't have time to debug cPy, and I didn't find a mPy port, so, I'll just go with a esp32 co-processor board and be done with it.

johncblacker
 
Posts: 163
Joined: Mon Aug 27, 2018 1:45 pm

Re: uPy socket vs cPy socket need help

by tannewt on Tue Mar 16, 2021 12:17 pm

The PR for MicroPython ESP32-S2 support is here: https://github.com/micropython/micropython/pull/6925

tannewt
 
Posts: 2396
Joined: Thu Oct 06, 2016 8:48 pm

Please be positive and constructive with your questions and comments.