I'm using the whatismyip
package to check my IP address before I call an IP sensitive API. The code runs in a loop and I'm finding after a few iterations I get the following error:
OSError: [Errno 48] Address already in use
From some searching I understand this is because whatismyip
is trying to use its designated port before it's been freed up.
I've tried creating an MRE to replicate the error:
import time
import whatismyip
EXPECTED_IP = "123.123.123.123"
while True:
current_ip_address = whatismyip.whatismyipv4()
if current_ip_address != EXPECTED_IP:
raise Exception
time.sleep(0.1) # simulate accessing IP sensitive API for info A
current_ip_address = whatismyip.whatismyipv4()
if current_ip_address != EXPECTED_IP:
raise Exception
time.sleep(0.1) # simulate accessing IP sensitive API for info B
current_ip_address = whatismyip.whatismyipv4()
if current_ip_address != EXPECTED_IP:
raise Exception
time.sleep(0.1) # simulate accessing IP sensitive API for info C
However, annoyingly it only spits out:
ResourceWarning: unclosed <socket.socket fd=73, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=('0.0.0.0', 54320)>
This looks related to my error but doesn't stop the code.
In the real code I've tried catching the OSError
and retrying whatismyip.whatismyipv4()
but this just generates the same error.
The error occurs on the last line of this block of code that I've extracted from the package:
SOURCE_IP = '0.0.0.0'
SOURCE_PORT = 54320
sockObj = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sockObj.settimeout(2)
sockObj.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sockObj.bind((SOURCE_IP, SOURCE_PORT))
In searching for solutions, most answers, e.g. this one, seem to recommend finding the process that uses the port and kill it. However, these don't provide any code I could include in my script. In addition to this I came across this post which says you can't get the OS to close a socket. It then recommends implementing the same code that's already above:
sockObj.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
I realise this isn't a perfect post because I can't replicate the error in an MRE but would anyone have any ideas how to solve this?
I'm using python 3.10.8 on MacOS 13.2.1.