W600 Air602 WiFi - Socket recv() is blocking?

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Post Reply
juergs
Posts: 4
Joined: Mon May 04, 2020 5:55 pm

W600 Air602 WiFi - Socket recv() is blocking?

Post by juergs » Mon May 04, 2020 6:10 pm

Hello,
with the W600 Air602 WiFi i want to build a TCP to Serial communication device.

My problem is that the implementation of
data = connection.recv(16)

is blocking, when a client is connected.

"select","poll" and connection_setblocking(0) samples where not working.

In order to not losse serial data, how to achieve a non-blocking mode?

Code Sample:

Code: Select all

import socket 
import sys 

def run():     
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = ('localhost', 23) 
    print('starting up on {} port {}'.format(*server_address)) 
    sock.bind(server_address)
    while (True):          
        print('waiting for a connection') 
        connection, client_address = sock.accept() 
        try: 
            print('connection from', client_address)         
            while (True): 
                data = connection.recv(16) 
                print('received {!r}'.format(data)) 
                if data: 
					print('sending data back to the client') 
                    connection.sendall(data) 
                else: 
                    print('no data from', client_address) 
                    break
		finally: 
			# Clean up the connection. 
			connection.close()
			print("closed. ")

User avatar
Roberthh
Posts: 1962
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: W600 Air602 WiFi - Socket recv() is blocking?

Post by Roberthh » Mon May 04, 2020 6:37 pm

Which version of the firmware are you using? You get that by either pushing Ctrl-B or by calling uos.uname().

juergs
Posts: 4
Joined: Mon May 04, 2020 5:55 pm

Re: W600 Air602 WiFi - Socket recv() is blocking?

Post by juergs » Mon May 04, 2020 7:41 pm

Code: Select all

MicroPython v1.10-284-g2eee4e2-dirty on 2019-11-08; WinnerMicro module with W600
Thought the most actual version …

regards Juergen

User avatar
Roberthh
Posts: 1962
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: W600 Air602 WiFi - Socket recv() is blocking?

Post by Roberthh » Mon May 04, 2020 7:57 pm

I rearranged a little bit you code, and tested it with telnet. What I see, that I can set the connection to nonblocking. Then the receive gets an EAGAIN exception. If I close the telnet session, them empty data is returned. That behaves identical on a W600 device and on a ESP32.
My W600 build is MicroPython v1.12-411-g4f9017aff-dirty on 2020-04-25; WinnerMicro module with W600
I took the code from WInnerMicro, fixed a few bugs not related to your question and re-compiled it with the recent Micropython. But with the test script you version should behave identical.

My test code:

Code: Select all

import socket
import sys
import time

def run():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_address = ('0.0.0.0', 23)
    print('starting up on {} port {}'.format(*server_address))
    sock.bind(server_address)
    sock.listen(0)
    while (True):
	print('waiting for a connection')
	connection, client_address = sock.accept()
	print('connection from', client_address)
	connection.setblocking(False)
	while (True):
	    try:
		data = connection.recv(16)
		print('received {!r}'.format(data))
		if data:
		    print('sending data back to the client')
		    connection.sendall(data)
		else:
		    print('No data: connection closed by the client')
		    break;
	    except Exception as e:
		print('Exception: ', e)
		print('no data from', client_address)
		time.sleep(1)

	# Clean up the connection.
	connection.close()
	print("closed. ")

run()

juergs
Posts: 4
Joined: Mon May 04, 2020 5:55 pm

Re: W600 Air602 WiFi - Socket recv() is blocking?

Post by juergs » Tue May 05, 2020 8:11 am

Hello roberthh,

thank you very much for pointing out to the fault.
setblocking relates to the connection and not to the socket object!

I also apreciated showing me the handling of no_data.

Full 10 points! ;-)

Thank you very, very much!
regards,
Juergen

juergs
Posts: 4
Joined: Mon May 04, 2020 5:55 pm

Re: W600 Air602 WiFi - Socket recv() is blocking?

Post by juergs » Tue May 05, 2020 10:07 am

I found the origin (usocket) of this misunderstanding:
socket.setblocking(flag)
Set blocking or non-blocking mode of the socket: if flag is false, the socket is set to non-blocking, else to blocking mode.
This method is a shorthand for certain settimeout() calls:
sock.setblocking(True) is equivalent to sock.settimeout(None) sock.setblocking(False) is equivalent to sock.settimeout(0)
Note, in quasi every doumentation i read, the "socket.setblocking(flag)" is bound to the socket- instead to the connection-object!
This may be a specific port feature, which may lead in the false direction, if this were mentioned in the documentation of the manufacturer ...
Or even your exsample of a socket-server in the original examples-directory would help so much.

Thank you again very much, for providing this solution.

Juergen

User avatar
Roberthh
Posts: 1962
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: W600 Air602 WiFi - Socket recv() is blocking?

Post by Roberthh » Tue May 05, 2020 10:20 am

socket.accept() returns a tuple, consisting of the a socket and an address. So in your script, the variable connection is of type socket.

Post Reply