在Python中关闭/重启套接字

时间:2011-02-17 14:33:30

标签: python sockets

我即将做一个简单的测试来使用PagSeguro(巴西“PayPal”),为此,我下载了他们的Python服务器以在我的localhost上进行测试。我在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 catch以便能够正确关闭套接字。谢谢大家!

5 个答案:

答案 0 :(得分:1)

您可以创建一个正确关闭套接字的函数,并使用atexit.register()将其注册为在程序终止时运行。见http://docs.python.org/library/atexit.html

答案 1 :(得分:1)

在终端窗口中使用以下命令终止 TCP 端口 28355:

npx 终止端口 28355

在我的 python 套接字服务器脚本中,我使用了以下几行:

导入操作系统 os.system("npx kill-port 28355")

此命令解决了“地址已在使用中”错误。 这是我找到的所有其他解决方案中唯一解决错误的解决方案,例如启用 SO_REUSEADDR 选项。

答案 2 :(得分:0)

如果你使用Ctrl + C来关闭进程,你可以尝试在代码中捕获KeyboardInterrupt异常(甚至更好,处理SIGINT信号)并在退出之前干净地关闭套接字。

当然,这不会阻止您以其他方式杀死您的应用程序并使用过时的套接字,但您也可以尝试处理这些情况。

答案 3 :(得分:0)

AFAIR SO_REUSEADDR的工作方式略有不同。

但你应该从什么开始 - 当你杀死你的工作服务器类型

netstat -tapdn | grep PORT

并将PORT替换为yoiur应用程序的PORT

您将获得有关套接字状态的信息....

答案 4 :(得分:0)

在OSX上,您可以使用以下命令终止端口(例如8000)

kill`lsof -i:8000 | grep Python |切-c8-11`

HTH