From 2d2c40b3d44bc7b73abb9534a7eeab3c27049b26 Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Thu, 11 Feb 2021 17:36:40 -0500 Subject: [PATCH] Add Socket tests --- tests/_manual/socketpool/client/cpy-client.py | 26 +++++++++++ .../_manual/socketpool/client/host-server.py | 27 +++++++++++ tests/_manual/socketpool/client/readme.md | 46 +++++++++++++++++++ tests/_manual/socketpool/datagram/ntp.py | 28 +++++++++++ tests/_manual/socketpool/datagram/readme.md | 19 ++++++++ tests/_manual/socketpool/server/cpy-server.py | 31 +++++++++++++ .../_manual/socketpool/server/host-client.py | 18 ++++++++ tests/_manual/socketpool/server/readme.md | 43 +++++++++++++++++ 8 files changed, 238 insertions(+) create mode 100644 tests/_manual/socketpool/client/cpy-client.py create mode 100644 tests/_manual/socketpool/client/host-server.py create mode 100644 tests/_manual/socketpool/client/readme.md create mode 100644 tests/_manual/socketpool/datagram/ntp.py create mode 100644 tests/_manual/socketpool/datagram/readme.md create mode 100644 tests/_manual/socketpool/server/cpy-server.py create mode 100644 tests/_manual/socketpool/server/host-client.py create mode 100644 tests/_manual/socketpool/server/readme.md diff --git a/tests/_manual/socketpool/client/cpy-client.py b/tests/_manual/socketpool/client/cpy-client.py new file mode 100644 index 0000000000..dcc742c9f8 --- /dev/null +++ b/tests/_manual/socketpool/client/cpy-client.py @@ -0,0 +1,26 @@ +import wifi +import socketpool +import ssl +import time + +TIMEOUT = None +HOST = '192.168.10.179' +PORT = 5000 + +# Connect to wifi +print("Connecting to wifi") +wifi.radio.connect("mySSID", "myPASS") +pool = socketpool.SocketPool(wifi.radio) + +print("Creating Socket") +with pool.socket(pool.AF_INET, pool.SOCK_STREAM) as s: + s.settimeout(TIMEOUT) + + print("Connecting") + s.connect((HOST, PORT)) + print("Sending") + sent = s.send(b'Hello, world') + print("Receiving") + buff = bytearray(128) + numbytes = s.recv_into(buff) +print(repr(buff)) diff --git a/tests/_manual/socketpool/client/host-server.py b/tests/_manual/socketpool/client/host-server.py new file mode 100644 index 0000000000..4a5faf2a00 --- /dev/null +++ b/tests/_manual/socketpool/client/host-server.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +import socket + +TIMEOUT = 10 +HOST = "192.168.10.179" +PORT = 5000 + +print("Create Socket") +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.settimeout(TIMEOUT) + s.bind((HOST, PORT)) + s.listen() + print("Accepting connections") + while True: + try: + conn, addr = s.accept() + break + except BlockingIOError: + pass + + with conn: + s.settimeout(TIMEOUT) + print('Connected by', addr) + data = conn.recv(128) + print("got: " + str(data)) + conn.sendall(data) + print("sent: " + str(data)) \ No newline at end of file diff --git a/tests/_manual/socketpool/client/readme.md b/tests/_manual/socketpool/client/readme.md new file mode 100644 index 0000000000..1ef0695314 --- /dev/null +++ b/tests/_manual/socketpool/client/readme.md @@ -0,0 +1,46 @@ +# Circuitpython as Client + +This example demonstrates the use of Socket as a client, accessing a server on a host development machine. This Circuitpython sketch uses the Connect, Send, and Recv_Into methods. + +## Prerequisites + +Circuitpython V6.2.0 minimum. Neither the host or client sketch has installed module prerequisites. + +## Setup + +Find a viable IP address for the host machine first and insert it in both sketches as HOST. On mac, this can be done by going to System Preferences/Network and checking the IP address used to connect to the local wireless network. Make sure that both devices are using the same WIFI! + +Each sketch can have Timeout values changed. The host sketch usually needs a value above 0, or the recv() will fail. Currently, Circuitpython's Connect function is always blocking, so changing the client timeout will not cause much change in behavior. + +Start the Server on the host PC first, within this folder: + +``` +python host-server.py +``` + +Then, reload the client sketch in Circuitpython. + +## Expected Behavior + +The example should connect to a server running on the host machine. The client will send a "Hello world" string to the server, which will return it. + +Expected client output: + +``` +Connecting to wifi +Creating Socket +Connecting +Sending +Receiving +bytearray(b'Hello, world') +``` + +Expected Server output (IP/port values will vary): + +``` +Create Socket +Accepting connections +Connected by ('192.168.10.128', 64509) +got: b'Hello, world' +sent: b'Hello, world' +``` \ No newline at end of file diff --git a/tests/_manual/socketpool/datagram/ntp.py b/tests/_manual/socketpool/datagram/ntp.py new file mode 100644 index 0000000000..31d922858a --- /dev/null +++ b/tests/_manual/socketpool/datagram/ntp.py @@ -0,0 +1,28 @@ +import wifi +import socketpool +import struct +import time + +# connect to wifi +print("Connecting to Wifi") +wifi.radio.connect("mySSID", "myPASS") +pool = socketpool.SocketPool(wifi.radio) + +# make socket +print("Creating socket") +sock = pool.socket(pool.AF_INET,pool.SOCK_DGRAM) + +# Fill packet +packet = bytearray(48) +packet[0] = 0b00100011 # Not leap second, NTP version 4, Client mode +NTP_TO_UNIX_EPOCH = 2208988800 # 1970-01-01 00:00:00 + +print("Sending packet") +sock.sendto(packet, ("pool.ntp.org", 123)) + +size, address = sock.recvfrom_into(packet) +print("Received packet") + +seconds = struct.unpack_from("!I", packet, offset=len(packet) - 8)[0] +print("Address:", address) +print("Time:", time.localtime(seconds - NTP_TO_UNIX_EPOCH)) diff --git a/tests/_manual/socketpool/datagram/readme.md b/tests/_manual/socketpool/datagram/readme.md new file mode 100644 index 0000000000..f63f0abccd --- /dev/null +++ b/tests/_manual/socketpool/datagram/readme.md @@ -0,0 +1,19 @@ +# Circuitpython Datagrams + +This example demonstrates using UDP (datagrams) with the Socket module, accessing the time from an NTP server using `sendto` and `recvfrom_into`. + +## Prerequisites + +Circuitpython V6.2.0 minimum. + +## Expected behavior + +The Circuitpython device will attempt to connect to wifi, and send a request for the time to `pool.ntp.org`. It will then convert the seconds returned into a unix time struct. + +Expected output: +``` +Sending packet +Received packet +Address: ('82.197.188.130', 31488) +Time: struct_time(tm_year=2021, tm_mon=2, tm_mday=11, tm_hour=22, tm_min=22, tm_sec=40, tm_wday=3, tm_yday=42, tm_isdst=-1) +``` diff --git a/tests/_manual/socketpool/server/cpy-server.py b/tests/_manual/socketpool/server/cpy-server.py new file mode 100644 index 0000000000..d865156bc8 --- /dev/null +++ b/tests/_manual/socketpool/server/cpy-server.py @@ -0,0 +1,31 @@ +import wifi +import socketpool + +TIMEOUT = None + +print("Connecting to Wifi") +wifi.radio.connect("mySSID", "myPASS") + +pool = socketpool.SocketPool(wifi.radio) + +print("Finding IP address") +print(wifi.radio.ipv4_address) +HOST = str(wifi.radio.ipv4_address) +PORT = 80 # Port to listen on + +print("Creating socket") +sock = pool.socket(pool.AF_INET,pool.SOCK_STREAM) + +sock.bind((HOST, PORT)) +sock.listen(1) +print("Accepting connections") +conn, addr = sock.accept() +with conn: + print('Connected by', addr) + buff = bytearray(128) + print("Receiving") + numbytes = conn.recvfrom_into(buff) + print(buff[:numbytes[0]]) + if numbytes: + print("Sending") + conn.send(buff[:numbytes[0]]) diff --git a/tests/_manual/socketpool/server/host-client.py b/tests/_manual/socketpool/server/host-client.py new file mode 100644 index 0000000000..b5aacbfa8e --- /dev/null +++ b/tests/_manual/socketpool/server/host-client.py @@ -0,0 +1,18 @@ +import socket + +HOST = '192.168.10.128' # The server's hostname or IP address +PORT = 80 # The port used by the server + +with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.settimeout(None) + + print("Connecting") + s.connect((HOST, PORT)) + + print("Sending") + s.send(b'Hello, world') + + print("Receiving") + data = s.recv(1024) + print('Received', repr(data)) + diff --git a/tests/_manual/socketpool/server/readme.md b/tests/_manual/socketpool/server/readme.md new file mode 100644 index 0000000000..26118b8f12 --- /dev/null +++ b/tests/_manual/socketpool/server/readme.md @@ -0,0 +1,43 @@ +# Circuitpython as Client + +This example demonstrates the use of Socket as a server, accessed by a client program on a host development machine. This Circuitpython sketch uses the Bind, Listen, Accept, and recvfrom_into calls. + +## Prerequisites + +Circuitpython V6.2.0 minimum. Neither the host or client sketch has installed module prerequisites. + +## Setup + +Make sure that both devices are using the same WIFI! The Circuitpython Server will automatically pick an IP and print it over the CDC monitor. Copy this value into the host client sketch. Start the Server on Circuitpython first, then run the client sketch in this folder: + +``` +python host-client.py +``` + +Each sketch can have Timeout values changed. + +## Expected behavior + +The host machine will connect to the server running on the Circuitpython device, and send a "Hello, world" string which is then returned. + +Expected client output: + +``` +Connecting +Sending +Receiving +Received b'Hello, world' +``` + +Expected server output: +``` +Connecting to Wifi +Finding IP address +192.168.10.128 +Creating socket +Accepting connections +Connected by ('192.168.10.179', 33274) +Receiving +bytearray(b'Hello, world') +Sending +```