From 0659bb5e25235cb0c0fbe5fb44b42ad75951b4bc Mon Sep 17 00:00:00 2001 From: Edward Wright Date: Sat, 22 Mar 2025 20:51:45 -0400 Subject: [PATCH 1/5] Raise exception in recv_from() in non-blocking mode --- adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py index 6694bef..c69d1ce 100644 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py @@ -632,7 +632,10 @@ def recv_into( # pylint: disable=unused-argument continue if self._timeout == 0: # non-blocking mode - break + if num_read == 0: + raise OSError(errno.EAGAIN) + else: + break if ticks_diff(ticks_ms(), last_read_time) / 1000 > self._timeout: raise OSError(errno.ETIMEDOUT) return num_read From 4fe3fe913d99026f37a47037f02650602dc49ae0 Mon Sep 17 00:00:00 2001 From: Edward Wright Date: Sat, 22 Mar 2025 20:53:35 -0400 Subject: [PATCH 2/5] Call _disconnect() from close() to match core socket behaviour --- adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py index c69d1ce..2266644 100644 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py @@ -705,6 +705,8 @@ def close(self) -> None: Mark the socket closed. Once that happens, all future operations on the socket object will fail. The remote end will receive no more data. """ + if self._sock_type == SocketPool.SOCK_STREAM: + self._disconnect() self._interface.release_socket(self._socknum) self._interface.socket_close(self._socknum) self._socket_closed = True From afedb1995f9ca5472b68e20aa58e186fcc7a6793 Mon Sep 17 00:00:00 2001 From: Edward Wright Date: Sat, 22 Mar 2025 20:57:56 -0400 Subject: [PATCH 3/5] Modify accept() behaviour to match core sockets --- .../adafruit_wiznet5k_socketpool.py | 67 ++++++++++++------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py index 2266644..0074909 100644 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py @@ -408,33 +408,50 @@ def accept( end of the connection. """ stamp = ticks_ms() - while self._status not in ( - wiznet5k.adafruit_wiznet5k.SNSR_SOCK_SYNRECV, - wiznet5k.adafruit_wiznet5k.SNSR_SOCK_ESTABLISHED, - wiznet5k.adafruit_wiznet5k.SNSR_SOCK_LISTEN, - ): + while True: + while self._status not in ( + wiznet5k.adafruit_wiznet5k.SNSR_SOCK_SYNRECV, + wiznet5k.adafruit_wiznet5k.SNSR_SOCK_ESTABLISHED, + wiznet5k.adafruit_wiznet5k.SNSR_SOCK_LISTEN, + ): + if ( + self._timeout + and 0 < self._timeout < ticks_diff(ticks_ms(), stamp) / 1000 + ): + raise TimeoutError("Failed to accept connection.") + if self._status == wiznet5k.adafruit_wiznet5k.SNSR_SOCK_CLOSE_WAIT: + self._disconnect() + self.listen() + if self._status == wiznet5k.adafruit_wiznet5k.SNSR_SOCK_CLOSED: + self.close() + self.listen() + + _, addr = self._interface.socket_accept(self._socknum) + # if any of the following conditions are true, we haven't accepted a connection if ( - self._timeout - and 0 < self._timeout < ticks_diff(ticks_ms(), stamp) / 1000 + addr[0] == "0.0.0.0" + or addr[1] == 0 + or self._interface.socket_status(self._socknum) != wiznet5k.adafruit_wiznet5k.SNSR_SOCK_ESTABLISHED ): - raise TimeoutError("Failed to accept connection.") - if self._status == wiznet5k.adafruit_wiznet5k.SNSR_SOCK_CLOSE_WAIT: - self._disconnect() - self.listen() - if self._status == wiznet5k.adafruit_wiznet5k.SNSR_SOCK_CLOSED: - self.close() - self.listen() - - _, addr = self._interface.socket_accept(self._socknum) - current_socknum = self._socknum - # Create a new socket object and swap socket nums, so we can continue listening - client_sock = Socket(self._socket_pool) - self._socknum = client_sock._socknum # pylint: disable=protected-access - client_sock._socknum = current_socknum # pylint: disable=protected-access - self._bind((None, self._listen_port)) - self.listen() - if self._status != wiznet5k.adafruit_wiznet5k.SNSR_SOCK_LISTEN: - raise RuntimeError("Failed to open new listening socket") + if self._timeout == 0: + # non-blocking mode + raise OSError(errno.EAGAIN) + elif self._timeout and 0 < self._timeout < ticks_diff(ticks_ms(), stamp) / 1000: + # blocking mode with timeout + raise OSError(errno.ETIMEDOUT) + else: + # blocking mode / timeout not expired + continue + current_socknum = self._socknum + # Create a new socket object and swap socket nums, so we can continue listening + client_sock = Socket(self._socket_pool) + self._socknum = client_sock._socknum # pylint: disable=protected-access + client_sock._socknum = current_socknum # pylint: disable=protected-access + self._bind((None, self._listen_port)) + self.listen() + if self._status != wiznet5k.adafruit_wiznet5k.SNSR_SOCK_LISTEN: + raise RuntimeError("Failed to open new listening socket") + break return client_sock, addr @_check_socket_closed From b6b66663898dceafa0353860dc79c13656de39c6 Mon Sep 17 00:00:00 2001 From: Edward Wright Date: Sat, 22 Mar 2025 23:32:20 -0400 Subject: [PATCH 4/5] Fix style issues flagged by Black and Pylint --- .../adafruit_wiznet5k_socketpool.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py index 0074909..c11d1e2 100644 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py @@ -431,17 +431,20 @@ def accept( if ( addr[0] == "0.0.0.0" or addr[1] == 0 - or self._interface.socket_status(self._socknum) != wiznet5k.adafruit_wiznet5k.SNSR_SOCK_ESTABLISHED + or self._interface.socket_status(self._socknum) + != wiznet5k.adafruit_wiznet5k.SNSR_SOCK_ESTABLISHED ): if self._timeout == 0: # non-blocking mode raise OSError(errno.EAGAIN) - elif self._timeout and 0 < self._timeout < ticks_diff(ticks_ms(), stamp) / 1000: + if ( + self._timeout + and 0 < self._timeout < ticks_diff(ticks_ms(), stamp) / 1000 + ): # blocking mode with timeout raise OSError(errno.ETIMEDOUT) - else: - # blocking mode / timeout not expired - continue + # blocking mode / timeout not expired + continue current_socknum = self._socknum # Create a new socket object and swap socket nums, so we can continue listening client_sock = Socket(self._socket_pool) @@ -586,7 +589,7 @@ def recvfrom( # pylint: disable=unused-argument ) @_check_socket_closed - def recv_into( # pylint: disable=unused-argument + def recv_into( # pylint: disable=unused-argument,too-many-branches self, buffer: bytearray, nbytes: int = 0, flags: int = 0 ) -> int: """ @@ -651,8 +654,7 @@ def recv_into( # pylint: disable=unused-argument # non-blocking mode if num_read == 0: raise OSError(errno.EAGAIN) - else: - break + break if ticks_diff(ticks_ms(), last_read_time) / 1000 > self._timeout: raise OSError(errno.ETIMEDOUT) return num_read From 4afaa8ba5352076f629fef343bd2141370d790ad Mon Sep 17 00:00:00 2001 From: Edward Wright Date: Sat, 22 Mar 2025 23:42:31 -0400 Subject: [PATCH 5/5] Fix style issue flagged by Black --- adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py index c11d1e2..5ab7a50 100644 --- a/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py +++ b/adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py @@ -425,7 +425,7 @@ def accept( if self._status == wiznet5k.adafruit_wiznet5k.SNSR_SOCK_CLOSED: self.close() self.listen() - + _, addr = self._interface.socket_accept(self._socknum) # if any of the following conditions are true, we haven't accepted a connection if (