s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
any_connection = False
while True:
try:
conn, addr = s.accept()
data = conn.recv(1024)
any_connection = True
# keep looking
if not data: continue
pid = os.fork()
if pid == 0:
server_process(data, conn)
except KeyboardInterrupt:
break
if any_connection:
print("Closing connection")
conn.close()
I'm catching the KeyboardInterrupt
signal here on an infinite-running TCP server I wrote in Python. However, even though I know it is closing the connection because it prints Closing Connection
, when I try to re-run the server I get:
OSError: [Errno 48] Address already in use
I have no idea what's happening because I know for sure I'm calling conn.close()
.
And running killall python3
doesn't fix it, I keep getting the error unless I wait for a long time or change port. Also I tried to grep all python3
processes but I get nothing.
I'm running OS X Yosemite.
When you are closing the client using ctrl + c , OS will stop the client process and close all the sockets opened by it.
close() call shuts down the socket associated with the socket descriptor socket, and frees resources allocated to the socket. If socket refers to an open TCP connection, the connection is closed. If a stream socket is closed when there is input data queued, the TCP connection is reset rather than being cleanly closed.
There's no need to call s.close() : with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: pass # Use the socket object without calling s.close(). The arguments passed to socket() are constants used to specify the address family and socket type. AF_INET is the Internet address family for IPv4.
As per the docs the error OSError: [Errno 48] Address already in use
occurs because
the previous execution of your script has left the socket in a TIME_WAIT state, and can’t be immediately reused. This can be resolved by using the socket.SO_REUSEADDR
flag.
For eg:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
You need to register a hook for this, something like:
#!/usr/bin/env python
import signal
import sys
def signal_handler(signal, frame):
# close the socket here
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With