Skip to content

Match core socket behaviour #178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 50 additions & 26 deletions adafruit_wiznet5k/adafruit_wiznet5k_socketpool.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,33 +408,53 @@ 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)
if (
self._timeout
and 0 < self._timeout < ticks_diff(ticks_ms(), stamp) / 1000
):
# blocking mode with timeout
raise OSError(errno.ETIMEDOUT)
# 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
Expand Down Expand Up @@ -569,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:
"""
Expand Down Expand Up @@ -632,6 +652,8 @@ def recv_into( # pylint: disable=unused-argument
continue
if self._timeout == 0:
# non-blocking mode
if num_read == 0:
raise OSError(errno.EAGAIN)
break
if ticks_diff(ticks_ms(), last_read_time) / 1000 > self._timeout:
raise OSError(errno.ETIMEDOUT)
Expand Down Expand Up @@ -702,6 +724,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
Expand Down