Я собираюсь провести простую тестовую реализацию с использованием PagSeguro (бразильский "PayPal"), и для этого я скачал их сервер Python для тестирования на моем локальном хосте. Я работаю на Mac, у меня есть сервер XAMPP (части Apache и MySQL во время моего процесса).
Моя проблема должна быть очень простой для тех, кто знает Python, сокеты и т. Д., И я нашел много подсказок в моих поисках информации. Однако - из-за моих слабых знаний в этой области я не смог соединить два и два, чтобы это исправить.
Короткий вопрос: как освободить сокет (из Терминала), чья программа вышла до того, как закрыла сокет. Alt - как мне сделать функцию Python для меня вызывающей, когда я хочу закрыть сокет и остановить / перезапустить сервер.
Сценарий:
Я запускаю сервер (в терминале с #: sudo python ./PagSeguroServer.py), и он работает нормально, я сделал несколько тестов, которые хотел. Затем мне нужно было изменить некоторые настройки сервера, и чтобы он работал, мне нужно перезагрузить сервер. Я решил, закрыв окно терминала, но затем, когда я снова открываю и набираю ту же команду, чтобы снова запустить сервер, я получаю «socket.error: [Errno 48] Адрес уже используется». Хорошо, я могу понять, почему, но не как это исправить, поэтому я гуглю это и нахожу подсказку для добавления
socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
в коде. Посмотрел класс Python и попытался поставить его там, насколько мне известно (как показано ниже). Тем не менее, не решил мою проблему. Так как мой «поиск и загадка», кажется, не в состоянии помочь мне - я сейчас бросаю его и вместо этого публикую этот персонализированный вопрос!
Это часть кода сервера:
class SecureHTTPServer(HTTPServer):
'''Servidor HTTPS com OpenSSL.'''
def __init__(self, server_address, HandlerClass,fpem):
BaseServer.__init__(self, server_address, HandlerClass)
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_privatekey_file (fpem)
ctx.use_certificate_file(fpem)
self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
self.socket_type))
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_bind()
self.server_activate()
....
def run(HandlerClass = HTTPSHandler, ServerClass = SecureHTTPServer):
'''Roda o servidor'''
server_address = ('', 443) # (address, port)
httpd = ServerClass(server_address, HandlerClass, fpem)
httpd.serve_forever()
if __name__ == '__main__':
run()
Примечание: Однажды мне действительно удалось открыть его - это было до того, как я добавил вызов setsockopt, и у меня возникло ощущение, что сокет закрылся после тайм-аута - где-то читал об этом. Это, однако, похоже, больше не повторится - ждали и пытались несколько раз.
Редактировать: В конце концов, я решил это следующим образом: необходимо убить процесс python, который удерживал сокет (см. Комментарий к ответу jd), затем добавил перехват KeyboardInterrupt, чтобы иметь возможность правильно закрыть сокет. Спасибо всем!