Разъем 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() 
  • django-admin.py и virtualenv проблема в Windows
  • Python: запись в новую строку файла
  • Ошибка авторизации кликов PyAutoGui
  • Использование PythonService.exe для размещения службы python при использовании virtualenv
  • ошибка при установке python pip rrdtool на windows 7
  • Переподготовка Tensorflow в Windows
  • Colorama для Python, не возвращая цветные линии печати в Windows
  • компилировать libdnet для python 2.7
  • Установщик Windows Python со всеми зависимостями?
  • Как определить версию порта USB в Windows?
  • Печать PDF-документа с помощью модуля win32print python?
  • Python - лучший язык программирования в мире.