Detailed information about this class can be found in usocket.
The following example sets up a server which can accept 5 connections in parallel, create a new thread for each connected client, receives and sends back data then close the socket.
import usocket import _thread import time # Thread for handling a client def client_thread(clientsocket,n): # Receive maxium of 12 bytes from the client r = clientsocket.recv(12) # If recv() returns with 0 the other end closed the connection if len(r) == 0: clientsocket.close() return else: # Do something wth the received data... print("Received: {}".format(str(r))) # Sends back some data clientsocket.send(str(n)) # Close the socket and terminate the thread clientsocket.close() # Set up server socket serversocket = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM) serversocket.setsockopt(usocket.SOL_SOCKET, usocket.SO_REUSEADDR, 1) serversocket.bind(("192.168.0.249", 6543)) # Accept maximum of 5 connections at the same time serversocket.listen(5) # Unique data to send back c = 0 while True: # Accept the connection of the clients (clientsocket, address) = serversocket.accept() # Start a new thread to handle the client _thread.start_new_thread(client_thread, (clientsocket, c)) c = c+1
The following example sets up a client which can connect to a server with 2 non-blocking sockets, create a new thread to handle the non-blocking sockets.
import socket import _thread import time import uerrno import uselect def socket_thread(p): while True: # Wait for any action to happen infinitely l = p.poll() # Start processing the actions happened for t in l: # First element of the returned tuple is the socket itself sock = t[0] # Second element of the returned tuple is the events happened event = t[1] # If any error or connection drop happened close the socket if(event & uselect.POLLERR or event & uselect.POLLHUP): sock.close() continue # If the socket is writable then send some data # The socket becomes writable if the connect() was successfull if(event & uselect.POLLOUT): # If any error occurs during sending here, do "nothing", poll() will return with error event, close the socket there try: sock.send("Data to send") # We only want to send one message on this socket, in the future wait only for new incoming messages p.modify(sock, uselect.POLLIN | uselect.POLLHUP | uselect.POLLERR) except: pass # If any new data is received then get it if(event & uselect.POLLIN): # If any error occurs during receiving here, do "nothing", poll() will return with error event, close the socket there try: r = sock.recv(1) # If recv() returns with 0 the other end closed the connection if len(r) == 0: sock.close() continue else: # Do something with the received data... print("Data received: " + str(r)) except: pass # List for storing our sockets socket_list = [] # Set up the first socket in non-blocking mode s1 = socket.socket() s1.setblocking(False) socket_list.append(s1) # Set up the second socket in non-blocking mode s2 = socket.socket() s2.setblocking(False) socket_list.append(s2) # Create a new poll object p = uselect.poll() # Register the sockets into the poll object, wait for all kind of events p.register(s1, uselect.POLLIN | uselect.POLLOUT | uselect.POLLHUP | uselect.POLLERR) p.register(s2, uselect.POLLIN | uselect.POLLOUT | uselect.POLLHUP | uselect.POLLERR) # Try to connect to the server with each sockets for s in socket_list: try: s.connect(socket.getaddrinfo("192.168.0.234", 6543)[0][-1]) except OSError as e: # In case of non-blocking socket the connect() raises eception of EINPROGRESS what is expected if e.args[0] != uerrno.EINPROGRESS: # Raise all other errors raise # Start the thread which takes care of the non-blocking sockets through the created poll object _thread.start_new_thread(socket_thread, (p,))
import socket import ssl import _thread import time import uerrno import uselect # Helper function for doing the handshake def handshake_helper(sock): while True: time.sleep_ms(1) try: # Perform the handshake sock.do_handshake() return except ssl.SSLError as e: # For now raise any other errors then TIMEOUT... if e.args[0] != ssl.SSL_TIMEOUT: raise def socket_thread(p): while True: # Wait for any action to happen infinitely l = p.poll() # Start processing the actions happened for t in l: # First element of the returned tuple is the socket itself sock = t[0] # Second element of the returned tuple is the events happened event = t[1] # If any error or connection drop happened close the socket if(event & uselect.POLLERR or event & uselect.POLLHUP): p.unregister(sock) sock.close() # If any new data is received then get it elif(event & uselect.POLLIN): # If any error occurs during receiving here, do "nothing", poll() will return with error event, close the socket there try: r = sock.recv(1) # If recv() returns with 0 the other end closed the connection if len(r) == 0: p.unregister(sock) sock.close() else: # Do something with the received data... print("Data received: " + str(r)) except: pass # If the socket is writable then we may expect it is connected, do handshake and send some data elif(event & uselect.POLLOUT): try: # Performing the SSL handshake handshake_helper(sock) except: # An error happened, close the socket, unregister it from poll p.unregister(sock) sock.close() # If any error occurs during sending here, do "nothing", poll() will return with error event, close the socket there try: sock.send("Data to send") # We only want to send one message on this socket, in the future wait only for new incoming messages p.modify(sock, uselect.POLLIN | uselect.POLLHUP | uselect.POLLERR) except: pass # Create and wrap the socket s = socket.socket() ssl_socket = ssl.wrap_socket(s, keyfile="/flash/cert/my_private_key.pem", certfile="/flash/cert/my_public_key.pem", server_side=False, cert_reqs=ssl.CERT_REQUIRED, ca_certs="/flash/cert/my_CA_cert.pem" ) # Set the wrapped socket to non-blocking ssl_socket.setblocking(False) # Create a new poll object p = uselect.poll() # Register the wrapped socket into the poll object, wait only for write and error events p.register(ssl_socket, uselect.POLLOUT | uselect.POLLHUP | uselect.POLLERR) # Try to connect to the server try: ssl_socket.connect(socket.getaddrinfo("192.168.0.234", 6543)[0][-1]) except OSError as e: # In case of non-blocking socket the connect() raises eception of EINPROGRESS what is expected if e.args[0] != uerrno.EINPROGRESS: # Raise all other errors raise # Start the thread which takes care of the non-blocking socket through the created poll object _thread.start_new_thread(socket_thread, (p))