Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are sockets closed in list comprehension but not in for loop?

I'm trying to create a list of available ports in Python. I am following this tutorial, but instead of printing the open ports, I'm adding them to a list.

Initially, I had something like the following:

available_ports = []

try:
    for port in range(1,8081):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        result = sock.connect_ex((remoteServerIP, port))
        if result == 0:
            available_ports.append(port)
        sock.close()

# ...

This clearly works fine, but it is well known that comprehensions are faster than loops, so I now have:

try:
    available_ports = [port for port in range(1, 8081) if not socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex((remoteServerIP, port))]

# ...

I assumed the sockets wouldn't be closed, but I tested it with the following:

try:
    available_ports = [port for port in range(1, 8081) if not socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect_ex((remoteServerIP, port))]

    for port in range(1,8081):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        result = sock.connect_ex((remoteServerIP, port))
        if result == 0:
            print("Port {}: \t Open".format(port))
        sock.close()

# ...

and indeed the open ports were printed.

Why are the sockets closed in the comprehension but not the for loop? Can I rely on this behavior or is this a red herring?

like image 546
erip Avatar asked Jan 11 '16 15:01

erip


1 Answers

There are no references left to your opened sockets, which means they are garbage collected. Sockets are closed as soon as they are garbage collected.

Exactly when the sockets from your list comprehension are garbage collected differs between Python implementations. CPython uses reference counting and therefore closes the sockets as soon as the last reference is dropped. Other implementations might defer the closing to the next GC cycle.

like image 85
Emil Vikström Avatar answered Sep 24 '22 13:09

Emil Vikström