Skip to content

Datagram issues #61

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

Closed
tom24 opened this issue Jul 1, 2022 · 1 comment
Closed

Datagram issues #61

tom24 opened this issue Jul 1, 2022 · 1 comment

Comments

@tom24
Copy link
Contributor

tom24 commented Jul 1, 2022

There are three issues:

socket.recvfrom result does not contain remote address
datagrams are not delimited on message boundary. For example, a recv(10) will contain data from 2 datagrams if two senders send datagrams of size 5
The UDP_SOCK scheme for keeping track of partially processed datagrams breaks down if there is more than one socket receiving datagrams.
Below is code.py for following tests.

Test 1:
Use the test code and edit bufsize=10,sleeptime=1,timeout=0
On source 1: echo src1 | nc -w 1 -u 192.168.0.99 5500
On source 2: echo src2 | nc -w 1 -u 192.168.0.99 5500
Then the system displays:
datagram from 0.0.0.0:0 Data: b'src1\nsrc2\n'
The messages from two sources are run together (and there
is no information in the address result)

Test 2:
Use the test code and edit bufsize=0,sleeptime=10,timeout=0
On source 1: echo src1 | nc -w 1 -u 192.168.0.99 5500
and wait for the message datagram from 0.0.0.0:0 Data: b'src1\n'
Then withing ten seconds do the next two sends:
On source 1: echo src1 | nc -w 1 -u 192.168.0.99 5500
On source 2: echo src2 | nc -w 1 -u 192.168.0.99 5500
Then the system displays:
datagram from 0.0.0.0:0 Data: b'src1\nsrc2\n'
The messages from two sources are run together (and there
is no information in the address result)

When implementing a fix, a decision has to be made -
what to do if the recv(bufize) is such that the full
datagram will not fit. To match behavior from other systems
it is decided that if the buffer will not hold the complete
datagram, then datagram contents up to the bufsize are
returned and the rest of the datagram is lost.

code.py for tests:

import board
import busio
import digitalio
import time
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
#from adafruit_wiznet5k.adafruit_wiznet5k import UDP_SOCK
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket

##SPI0
SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17

##reset
W5x00_RSTn = board.GP20

print("datagram test")

# Setup your network configuration below
# random MAC, later should change this value on your vendor ID
MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05)
IP_ADDRESS = (192,168,0,99)                              # change to match network
SUBNET_MASK = (255, 255, 255, 0)
GATEWAY_ADDRESS = (192,168,0,1)                   # change to match network
DNS_SERVER = (8, 8, 8, 8)

led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT

ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT

# For Adafruit Ethernet FeatherWing
cs = digitalio.DigitalInOut(SPI0_CSn)
# For Particle Ethernet FeatherWing
# cs = digitalio.DigitalInOut(board.D5)

spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)

# Reset W5500 first
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True
time.sleep(0.1)


# Initialize ethernet interface with DHCP
eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC, debug=False)
eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)
print("Chip Version:", eth.chip)
print("MAC Address:", [hex(i) for i in eth.mac_address])
print("My IP address is:", eth.pretty_ip(eth.ip_address))

# init socket lib
socket.set_interface(eth)

# test parameters
bufsize = 0    # set to 0 or some non-zero value to test different situations
sleeptime = 10   # set large to test case of datagrams from two sources run together
timeout=0       # set depending on test

sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)  # Allocate socket for the server
port = 5500
sock.bind((None,port))
print("Listening for datagram on port {}".format(port))
sock.settimeout(timeout)
while True:
    with sock:
        while True:
            led.value = not led.value
            time.sleep(sleeptime)
            data, addr = sock.recvfrom(bufsize)
            if data:
                print("datagram from {}:{} Data: {}".format(addr[0], addr[1], data))
            elif bufsize:
                # timeout is not relevant if bufize==0, since recvfrom
                # returns immediately if no data
                print("No data, timeout")
@tekktrik
Copy link
Member

Resolved via #62

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants