Reputation: 71
I am writing a program to send/receive data to a device using an IPv6 UDP port. My python code is running on a Win7 platform and the device is a piece of custom hardware. The PC and device are directly connected and do not get routed through a LAN.
The program work... sort of. When I initially attempt to send a message to the device, the send fails. To be more specific, as viewed by wireshark, I never see the message get sent to the device. When I ping the device using ping <ipv6_addr> -t
on the command line, the first 1 or 2 attempts fail, after which, the pings start being received. I kill the ping and attempt to send the message just as before, but now it succeeds. Wireshark now shows all the messages. If I keep sending messages over a relatively short duration (somewhere between 10 sec to a 2 minute), the program works as expected. If I wait longer, my message will once again not be sent. If I keep the ping program continuously pinging, my messages also get sent regardless of the time between message sending activity. Here is my code:
import socket
def connect(port):
if socket.has_ipv6:
client = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
client.bind(('', port))
client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
client.settimeout(0.25)
def send_data(addr, port, data):
client.sendto(data, (addr, port))
def main_app():
connect(10000)
bin_data = binascii.a2b_hex('deadbeef')
# Do some processing
send_data(<ipv6_address>, 10000, bin_data)
Some googling did not yield any good leads on whether the problem is Python or something else, so I figured I would start with the Python as see where it takes me.
Any assistance would be greatly appreciated!
Upvotes: 0
Views: 1818
Reputation: 71
After some digging around I believe I found my problem. I was not including the IP address of the PC running the python in my bind statement. So changing my connect() function above to
def connect(self):
# ...
client.bind(('fe80::', port))
# ...
allowed my messages to be sent consistently. Im pretty new to socket programming, so can anyone provide an explanation why this fix works?
Thanks
Upvotes: 1
Reputation: 8614
Couple of hints:
Call client.setsockopt()
before you call client.bind()
.
You need to call socket.close()
when you are done with the socket.
What i suspect to be the reason behind the weird issues with ping and timing issues could be the combination of a low timeout value and the NDP caching.
The timeout of 0.25
is probably for some reason too low for NDP resolution + data transmission to complete (maybe your embedded device stack is slow). When you do the ping, it does NDP for you, and creates a cached info that you can use from your app, without breaking the timeout limit.
I would suggest trying to up the limit: client.settimeout(2)
Upvotes: 0