2016-01-11 12 views
5

Python'da kullanılabilir bağlantı noktalarının bir listesini oluşturmaya çalışıyorum. this tutorial'u izliyorum, ancak açık bağlantı noktalarını yazdırmak yerine, bunları bir listeye ekliyorum.Soketler neden liste anlamada kapalı, ancak for döngüsünde değiller?

Başlangıçta, aşağıdaki gibi bir şey vardı: Bu açıkça çalışıyor

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() 

# ... 

, ama iyi comprehensions are faster than loops bilinmektedir, bu yüzden şimdi vardır:

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

# ... 

Ben soketleri kabul gitmeyeceklerini kapatılmamış, ancak aşağıdakilerle test ettim:

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() 

# ... 

ve aslında Açık portlar basılmıştır.

Soketler neden kavramada kapalıdır, ancak döngü için değil? Bu davranışa güvenebilir miyim yoksa bu kırmızı bir ringa mı?

cevap

8

Açtığınız soketlere atıfta bulunulmamış, yani çöpler toplanmış demektir. Soketler as soon as they are garbage collected kapalıdır.

Tam olarak listenizdeki soketlerin toplandığı çöpler toplandığında Python uygulamaları arasında farklar vardır. CPython referans sayımı kullanır ve bu nedenle son referans düştüğü anda soketleri kapatır. Diğer uygulamalar bir sonraki GC döngüsüne kapanmayı erteleyebilir.

+0

İlginç. Referansları manuel olarak GC için bir yol olsa bile, pythonic olmazdı. Aynı zamanda kavrama içindeki soketleri kapatmanın bir yolu olduğunu sanmıyorum ('' açık (soket) 'ile). Limanlar 'eklemek' için sadece birkaç milisaniye gerekir. – erip

+1

Bu gerçekten farklı bir sorudur, ancak soketin kapanmasını garantiye almanız gerekiyorsa, sadece 'for' döngüsünü tercih etmeniz gerektiğini düşünüyorum. –

+0

Hiçbir soru - sadece sözler. Yardım ve referansları takdir ediyorum. – erip

İlgili konular