Разъем Python не закрывает соединение должным образом

Я новичок в программировании сокетов и столкнулся с загадочной проблемой:

У меня есть программа Windows, которую я не могу изменить (проприетарное программное обеспечение), но которая пытается подключиться к определенному ip и порту с помощью tcp-сокета.

В моем ящике linux я написал небольшой скрипт python для работы сокета в win prog. Это отлично работает, пока я не убью свою проги на linux. Исходный серверный сокет не закрывается, как указано, и я не могу перезапустить свою программу до тех пор, пока сокет не будет собран мусором.

Если я попробую то же самое с linux-сокетом (в отдельном скрипте python), у меня проблем нет.

Вот пример минимального кода:

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

Если я убью это с помощью Ctrl-C, он нормально выйдет. Но после перезапуска скрипта я получаю socket.error, указав, что адрес уже используется. Через минуту или около того программа снова работает.

Я также попробовал закрыть перед закрытием (aka conn.shutdown (2) и server.shutdown …), но это не имеет никакого эффекта.

Есть ли лучший «правильный» способ закрыть сокет Windows? Я пропустил что-то фундаментальное в отношении сокетов в целом?

Благодаря!

edit: Я думаю, что я только что увидел ответ здесь: какой правильный способ закрыть сокет в python 2.6?

Хотя я использую python 2.5, он все равно может работать.

2 Solutions collect form web for “Разъем Python не закрывает соединение должным образом”

Вы испытываете TIME_WAIT подключенных сокетов. Несмотря на то, что вы закрыли свой сокет, он все еще имеет длительные последствия в течение пары минут. Причины этого, а также флаг сокета, который вы можете установить для отключения поведения (SO_REUSEADDR), объясняются в FAQ для часто задаваемых разделов UNIX .

Вкратце,

 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

Попробуйте добавить импорт sys и завершите свое приложение с помощью sys.exit (). Сокет остается зарезервированным до тех пор, пока система не будет удовлетворена тем, что приложение закрыто. Вы можете быть явным о том, что с помощью sys.exit ()

[править] О, хорошо. Я довольно новичок в своих сокетах. Значит, вы говорите, что эта последовательность небезопасна? Я не могу представить себе другого способа сделать это. Вы должны закрыть свое приложение в какой-то момент, с некоторой техникой, не так ли? Как это правильно сделать?

 server.shutdown(socket.SHUT_RDWR) server.close() sys.exit() 
  • Не удается запустить PhantomJS с Python в Windows 7
  • Ошибка Python os.walk и japanese filename
  • Как создать временный файл, который может быть прочитан подпроцессом?
  • Как установить python 3.2.3 на предприятие Windows 7
  • доступ на доступ к папке запрещен в Windows
  • Добавить расширенные функции в текстовый виджет tkinter
  • В Python, как я могу проверить, существует ли накопитель без бросания ошибки для съемных дисков?
  • Не удалось загрузить подстроки python для Subversion
  • Python - лучший язык программирования в мире.