Skip to content

Commit 735bb43

Browse files
authored
Merge pull request #31 from xorbit/master
Socket improvements
2 parents f71ca90 + f4a959c commit 735bb43

File tree

2 files changed

+78
-45
lines changed

2 files changed

+78
-45
lines changed

adafruit_wiznet5k/adafruit_wiznet5k.py

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -472,33 +472,20 @@ def socket_available(self, socket_num, sock_type=SNMR_TCP):
472472
print("* socket_available called with protocol", sock_type)
473473
assert socket_num <= self.max_sockets, "Provided socket exceeds max_sockets."
474474

475-
if sock_type == 0x02:
476-
# flush by reading remaining data from previous packet
477-
while UDP_SOCK["bytes_remaining"] > 0 and self.socket_read(socket_num, 1):
478-
if self._debug:
479-
print("Flushing {} bytes".format(UDP_SOCK["bytes_remaining"]))
480-
if UDP_SOCK["bytes_remaining"] > 0:
481-
UDP_SOCK["bytes_remaining"] = UDP_SOCK["bytes_remaining"] - 1
482-
483475
res = self._get_rx_rcv_size(socket_num)
484476

485477
if sock_type == SNMR_TCP:
486478
return res
487479
if res > 0:
480+
if UDP_SOCK["bytes_remaining"]:
481+
return UDP_SOCK["bytes_remaining"]
488482
# parse the udp rx packet
489-
ret = 0
490483
# read the first 8 header bytes
491484
ret, self._pbuff = self.socket_read(socket_num, 8)
492485
if ret > 0:
493-
UDP_SOCK["remote_ip"] = self._pbuff
494-
UDP_SOCK["remote_port"] = self._pbuff[4]
495-
UDP_SOCK["remote_port"] = (UDP_SOCK["remote_port"] << 8) + self._pbuff[
496-
5
497-
]
498-
UDP_SOCK["bytes_remaining"] = self._pbuff[6]
499-
UDP_SOCK["bytes_remaining"] = (
500-
UDP_SOCK["bytes_remaining"] << 8
501-
) + self._pbuff[7]
486+
UDP_SOCK["remote_ip"] = self._pbuff[:4]
487+
UDP_SOCK["remote_port"] = (self._pbuff[4] << 8) + self._pbuff[5]
488+
UDP_SOCK["bytes_remaining"] = (self._pbuff[6] << 8) + self._pbuff[7]
502489
ret = UDP_SOCK["bytes_remaining"]
503490
return ret
504491
return 0

adafruit_wiznet5k/adafruit_wiznet5k_socket.py

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def is_ipv4(host):
8484
return True
8585

8686

87-
# pylint: disable=invalid-name
87+
# pylint: disable=invalid-name, too-many-public-methods
8888
class socket:
8989
"""A simplified implementation of the Python 'socket' class
9090
for connecting to a Wiznet5k module.
@@ -112,11 +112,12 @@ def __enter__(self):
112112
return self
113113

114114
def __exit__(self, exc_type, exc_val, exc_tb):
115-
self.disconnect()
116-
stamp = time.monotonic()
117-
while self.status == adafruit_wiznet5k.SNSR_SOCK_FIN_WAIT:
118-
if time.monotonic() - stamp > 1000:
119-
raise RuntimeError("Failed to disconnect socket")
115+
if self._sock_type == SOCK_STREAM:
116+
self.disconnect()
117+
stamp = time.monotonic()
118+
while self.status == adafruit_wiznet5k.SNSR_SOCK_FIN_WAIT:
119+
if time.monotonic() - stamp > 1000:
120+
raise RuntimeError("Failed to disconnect socket")
120121
self.close()
121122
stamp = time.monotonic()
122123
while self.status != adafruit_wiznet5k.SNSR_SOCK_CLOSED:
@@ -216,18 +217,19 @@ def accept(self):
216217
return client_sock, addr
217218

218219
def connect(self, address, conntype=None):
219-
"""Connect to a remote socket at address. (The format of address depends
220-
on the address family — see above.)
220+
"""Connect to a remote socket at address.
221221
:param tuple address: Remote socket as a (host, port) tuple.
222-
223222
"""
224223
assert (
225224
conntype != 0x03
226225
), "Error: SSL/TLS is not currently supported by CircuitPython."
227226
host, port = address
228227

229228
if hasattr(host, "split"):
230-
host = tuple(map(int, host.split(".")))
229+
try:
230+
host = tuple(map(int, host.split(".")))
231+
except ValueError:
232+
host = _the_interface.get_host_by_name(host)
231233
if not _the_interface.socket_connect(
232234
self.socknum, host, port, conn_mode=self._sock_type
233235
):
@@ -238,23 +240,29 @@ def send(self, data):
238240
"""Send data to the socket. The socket must be connected to
239241
a remote socket.
240242
:param bytearray data: Desired data to send to the socket.
241-
242243
"""
243244
_the_interface.socket_write(self.socknum, data, self._timeout)
244245
gc.collect()
245246

246-
def recv(self, bufsize=0): # pylint: disable=too-many-branches
247+
def sendto(self, data, address):
248+
"""Send data to the socket. The socket must be connected to
249+
a remote socket.
250+
:param bytearray data: Desired data to send to the socket.
251+
:param tuple address: Remote socket as a (host, port) tuple.
252+
"""
253+
self.connect(address)
254+
return self.send(data)
255+
256+
def recv(self, bufsize=0, flags=0): # pylint: disable=too-many-branches
247257
"""Reads some bytes from the connected remote address.
248258
:param int bufsize: Maximum number of bytes to receive.
259+
:param int flags: ignored, present for compatibility.
249260
"""
250261
# print("Socket read", bufsize)
251262
if bufsize == 0:
252263
# read everything on the socket
253264
while True:
254-
if self._sock_type == SOCK_STREAM:
255-
avail = self.available()
256-
elif self._sock_type == SOCK_DGRAM:
257-
avail = _the_interface.udp_remaining()
265+
avail = self.available()
258266
if avail:
259267
if self._sock_type == SOCK_STREAM:
260268
self._buffer += _the_interface.socket_read(self.socknum, avail)[
@@ -275,10 +283,7 @@ def recv(self, bufsize=0): # pylint: disable=too-many-branches
275283
received = []
276284
while to_read > 0:
277285
# print("Bytes to read:", to_read)
278-
if self._sock_type == SOCK_STREAM:
279-
avail = self.available()
280-
elif self._sock_type == SOCK_DGRAM:
281-
avail = _the_interface.udp_remaining()
286+
avail = self.available()
282287
if avail:
283288
stamp = time.monotonic()
284289
if self._sock_type == SOCK_STREAM:
@@ -305,21 +310,62 @@ def recv(self, bufsize=0): # pylint: disable=too-many-branches
305310
gc.collect()
306311
return ret
307312

313+
def recvfrom(self, bufsize=0, flags=0):
314+
"""Reads some bytes from the connected remote address.
315+
:param int bufsize: Maximum number of bytes to receive.
316+
:param int flags: ignored, present for compatibility.
317+
:returns: a tuple (bytes, address) where address is a tuple (ip, port)
318+
"""
319+
return (
320+
self.recv(bufsize),
321+
(
322+
_the_interface.remote_ip(self.socknum),
323+
_the_interface.remote_port(self.socknum),
324+
),
325+
)
326+
327+
def recv_into(self, buf, nbytes=0, flags=0):
328+
"""Reads some bytes from the connected remote address info the provided buffer.
329+
:param bytearray buf: Data buffer
330+
:param nbytes: Maximum number of bytes to receive
331+
:param int flags: ignored, present for compatibility.
332+
:returns: the number of bytes received
333+
"""
334+
if nbytes == 0:
335+
nbytes = len(buf)
336+
ret = self.recv(nbytes)
337+
nbytes = len(ret)
338+
buf[:nbytes] = ret
339+
return nbytes
340+
341+
def recvfrom_into(self, buf, nbytes=0, flags=0):
342+
"""Reads some bytes from the connected remote address info the provided buffer.
343+
:param bytearray buf: Data buffer
344+
:param nbytes: Maximum number of bytes to receive
345+
:param int flags: ignored, present for compatibility.
346+
:returns a tuple (nbytes, address) where address is a tuple (ip, port)
347+
"""
348+
return (
349+
self.recv_into(buf, nbytes),
350+
(
351+
_the_interface.remote_ip(self.socknum),
352+
_the_interface.remote_port(self.socknum),
353+
),
354+
)
355+
308356
def readline(self):
309357
"""Attempt to return as many bytes as we can up to \
310358
but not including '\r\n'.
311359
312360
"""
313361
stamp = time.monotonic()
314362
while b"\r\n" not in self._buffer:
315-
if self._sock_type == SOCK_STREAM:
316-
avail = self.available()
317-
if avail:
363+
avail = self.available()
364+
if avail:
365+
if self._sock_type == SOCK_STREAM:
318366
self._buffer += _the_interface.socket_read(self.socknum, avail)[1]
319-
elif self._sock_type == SOCK_DGRAM:
320-
avail = _the_interface.udp_remaining()
321-
if avail:
322-
self._buffer += _the_interface.read_udp(self.socknum, avail)
367+
elif self._sock_type == SOCK_DGRAM:
368+
self._buffer += _the_interface.read_udp(self.socknum, avail)[1]
323369
if (
324370
not avail
325371
and self._timeout > 0

0 commit comments

Comments
 (0)