windows - Python socket lukker ikke forbindelsen korrekt

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg er ny til sokkel programmering og løb ind i et forbløffende problem:


Jeg har et Windows-program, som jeg ikke kan ændre (proprietær software), men som forsøger at forbinde til en bestemt IP og port med en TCP-stik.


På min Linux-boks skrev jeg et lille python-script til at tjene stikket til win-prog. Dette virker fint, indtil jeg dræber min prog på linux. Den indledende serverkontakt lukker ikke som angivet, og jeg kan ikke genstarte mit program, indtil stikkontakten er opsamlet.


Hvis jeg prøver det samme med en linux socket (i et separat python script) har jeg ingen problemer.


Her er et minimalt kodeeksempel:


import socket

server = socket.socket()
server.bind(('192.168.0.111', 50001))
server.listen(1)
conn, addr = server.accept()
print 'Connection established'

running = True
while running:
    try:
        data = conn.recv(4096)
    except KeyboardInterrupt:
        conn.close()
        running = False
    else:
        if data:
            print data
        else:
            conn.close()
            running = False
server.close()


Hvis jeg dræber dette med Ctrl-C, udgår det normalt. Men ved genstart af scriptet får jeg en socket.error, der angiver, at adressen allerede er i brug. Efter et minut eller så fungerer programmet igen.


Jeg har også forsøgt en shutdown før afslutningen (aka conn.shutdown (2) og server.shutdown ...) men det har ingen effekt.


Er der en bedre 'rigtig' måde at lukke en Windows-stik på? Savner jeg noget grundlæggende om stik i almindelighed?


Tak!


redigere: Jeg tror jeg lige så svaret her:
Hvad er den rigtige måde at lukke en stikkontakt på i python 2.6?


Selvom jeg bruger python 2.5, kan det stadig arbejde.

Bedste reference


Du oplever TIME\_WAIT tilstanden for tilsluttede stikkontakter. Selvom du har lukket din stikkontakt, har det stadig dårlige konsekvenser i et par minutter. Årsagerne til dette samt et socketflag, du kan indstille til at deaktivere adfærd (SO\_REUSEADDR), forklares i UNIX-guiden sokkel FAQ. [6]


Kort sagt,


server.setsockopt(socket.SOL\_SOCKET, socket.SO\_REUSEADDR, 1)

Andre referencer 1


Prøv at tilføje import sys og afslutte din app med sys.exit (). Stikket forbliver forbeholdt, indtil systemet er tilfreds med, at ansøgningen er lukket. Du kan være eksplicit om det med sys.exit ()


[[rediger]] Åh, okay. Jeg er ret ny til stik selv. Så du siger, at denne sekvens ikke er sikker? Jeg kan ikke forestille mig nogen anden måde at gøre det på. Du skal lukke din app på et eller andet tidspunkt, med en eller anden teknik, ikke? Hvordan går det så korrekt ud?


server.shutdown(socket.SHUT\_RDWR) 
server.close()
sys.exit()